From 3c6b85469bdd031fc71161535559f7d14e210683 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Mon, 26 Jul 2021 15:26:29 +0200 Subject: [PATCH] [Lens] Move Lens functions to `common` (#105455) * :truck: First move batch to common * :truck: Second batch of move * :label: Import types only * :truck: Third batch * :truck: Fourth batch move * :truck: Another module moved * :truck: More function moved * :truck: Last bit of move * :zap: Reduce page load bundle size * :bug: Fix import issue * :bug: More import fix * :sparkles: Registered functions on the server * :bug: Expose datatable_column as well * :white_check_mark: Add server side expression test * :truck: Moved back render functions to public * :sparkles: Add a timezone arg to time_scale * :fire: Remove timezone arg * :fire: Remove server side code for now * :ok_hand: Integrated feedback * :truck: Move back datatable render function * :label: Fix imports * :label: Fix missing export * :truck: Move render functions back! Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../counter_rate/counter_rate.test.ts | 2 +- .../expressions}/counter_rate/index.ts | 5 +- .../common/expressions/datatable/datatable.ts | 158 ++++++ .../expressions/datatable/datatable_column.ts | 85 +++ .../common/expressions/datatable/index.ts | 12 + .../expressions/datatable}/sorting.test.tsx | 0 .../expressions/datatable}/sorting.tsx | 2 +- .../expressions/datatable}/summary.test.ts | 2 +- .../expressions/datatable}/summary.ts | 10 +- .../datatable}/transpose_helpers.test.ts | 4 +- .../datatable}/transpose_helpers.ts | 19 +- .../expressions/datatable}/utils.ts | 4 +- .../format_column}/format_column.test.ts | 2 +- .../expressions/format_column/index.ts} | 4 +- .../heatmap_chart/heatmap_chart.ts | 122 +++++ .../expressions/heatmap_chart/heatmap_grid.ts | 114 ++++ .../heatmap_chart/heatmap_legend.ts | 64 +++ .../common/expressions/heatmap_chart/index.ts | 10 + .../plugins/lens/common/expressions/index.ts | 17 + .../expressions/merge_tables/index.ts} | 16 +- .../merge_tables}/merge_tables.test.ts | 2 +- .../common/expressions/metric_chart/index.ts | 9 + .../expressions/metric_chart/metric_chart.ts | 68 +++ .../expressions/metric_chart}/types.ts | 0 .../common/expressions/pie_chart/index.ts | 9 + .../common/expressions/pie_chart/pie_chart.ts | 103 ++++ .../expressions/pie_chart}/types.ts | 4 +- .../expressions/rename_columns/index.ts | 8 + .../rename_columns}/rename_columns.test.ts | 4 +- .../rename_columns}/rename_columns.ts | 14 +- .../common/expressions/time_scale/index.ts | 9 + .../time_scale}/time_scale.test.ts | 46 +- .../expressions/time_scale/time_scale.ts | 151 ++++++ .../common/expressions/time_scale/types.ts | 8 + .../expressions/xy_chart/axis_config.ts | 171 ++++++ .../expressions/xy_chart/fitting_function.ts | 58 ++ .../expressions/xy_chart/grid_lines_config.ts | 51 ++ .../lens/common/expressions/xy_chart/index.ts | 16 + .../expressions/xy_chart/layer_config.ts | 120 +++++ .../expressions/xy_chart/legend_config.ts | 110 ++++ .../expressions/xy_chart/series_type.ts | 18 + .../xy_chart/tick_labels_config.ts | 51 ++ .../common/expressions/xy_chart/xy_args.ts | 39 ++ .../common/expressions/xy_chart/xy_chart.ts | 156 ++++++ x-pack/plugins/lens/common/index.ts | 3 + .../suffix_formatter/index.ts} | 6 +- .../suffix_formatter.test.ts | 2 +- x-pack/plugins/lens/common/types.ts | 34 +- .../components/cell_value.test.tsx | 11 +- .../components/cell_value.tsx | 6 +- .../components/columns.tsx | 4 +- .../components/dimension_editor.tsx | 14 +- .../components/table_actions.test.ts | 5 +- .../components/table_actions.ts | 14 +- .../components/table_basic.test.tsx | 4 +- .../components/table_basic.tsx | 23 +- .../components/types.ts | 14 +- .../expression.test.tsx | 5 +- .../datatable_visualization/expression.tsx | 184 +------ .../public/datatable_visualization/index.ts | 11 +- .../datatable_visualization/visualization.tsx | 32 +- .../public/editor_frame_service/service.tsx | 2 +- .../embeddable/embeddable_component.tsx | 3 +- .../heatmap_visualization/chart_component.tsx | 6 +- .../dimension_editor.tsx | 6 +- .../heatmap_visualization/expression.tsx | 220 +------- .../public/heatmap_visualization/index.ts | 9 +- .../heatmap_visualization/suggestions.test.ts | 4 +- .../heatmap_visualization/suggestions.ts | 4 +- .../toolbar_component.tsx | 4 +- .../public/heatmap_visualization/types.ts | 50 +- .../visualization.test.ts | 4 +- .../heatmap_visualization/visualization.tsx | 7 +- x-pack/plugins/lens/public/index.ts | 16 +- .../dimension_panel/dimension_panel.tsx | 2 +- .../dimension_panel/time_scaling.tsx | 4 +- .../public/indexpattern_datasource/index.ts | 4 +- .../indexpattern_datasource/indexpattern.tsx | 14 +- .../definitions/calculations/utils.ts | 2 +- .../operations/definitions/column_types.ts | 2 +- .../operations/definitions/ranges/ranges.tsx | 2 +- .../operations/layer_helpers.ts | 2 +- .../operations/time_scale_utils.test.ts | 2 +- .../operations/time_scale_utils.ts | 4 +- .../indexpattern_datasource/time_scale.ts | 150 ------ .../indexpattern_datasource/to_expression.ts | 3 +- .../metric_visualization/expression.test.tsx | 6 +- .../metric_visualization/expression.tsx | 66 +-- .../lens/public/metric_visualization/index.ts | 7 +- .../metric_suggestions.ts | 2 +- .../visualization.test.ts | 2 +- .../metric_visualization/visualization.tsx | 2 +- .../public/pie_visualization/expression.tsx | 102 +--- .../lens/public/pie_visualization/index.ts | 11 +- .../render_function.test.tsx | 4 +- .../pie_visualization/render_function.tsx | 5 +- .../pie_visualization/suggestions.test.ts | 2 +- .../public/pie_visualization/suggestions.ts | 4 +- .../public/pie_visualization/to_expression.ts | 2 +- .../lens/public/pie_visualization/toolbar.tsx | 6 +- .../pie_visualization/visualization.test.ts | 2 +- .../pie_visualization/visualization.tsx | 6 +- .../coloring/color_stops.tsx | 2 +- .../shared_components/coloring/constants.ts | 2 +- .../shared_components/coloring/index.ts | 1 - .../coloring/palette_configuration.test.tsx | 4 +- .../coloring/palette_configuration.tsx | 4 +- .../coloring/palette_panel_container.tsx | 3 +- .../coloring/palette_picker.tsx | 6 +- .../shared_components/coloring/types.ts | 25 - .../shared_components/coloring/utils.ts | 4 +- x-pack/plugins/lens/public/types.ts | 14 +- .../axes_configuration.test.ts | 2 +- .../xy_visualization/axes_configuration.ts | 5 +- .../axis_settings_popover.tsx | 2 +- .../xy_visualization/color_assignment.test.ts | 4 +- .../xy_visualization/color_assignment.ts | 9 +- .../xy_visualization/expression.test.tsx | 27 +- .../public/xy_visualization/expression.tsx | 172 +----- .../xy_visualization/fitting_functions.ts | 52 +- .../get_legend_action.test.tsx | 4 +- .../xy_visualization/get_legend_action.tsx | 5 +- .../lens/public/xy_visualization/index.ts | 11 +- .../public/xy_visualization/state_helpers.ts | 5 +- .../public/xy_visualization/to_expression.ts | 3 +- .../lens/public/xy_visualization/types.ts | 502 +----------------- .../line_curve_option.tsx | 2 +- .../missing_values_option.tsx | 4 +- .../visual_options_popover.test.tsx | 2 +- .../visual_options_popover.tsx | 4 +- .../xy_visualization/visualization.test.ts | 3 +- .../public/xy_visualization/visualization.tsx | 5 +- .../lens/public/xy_visualization/x_domain.tsx | 4 +- .../xy_visualization/xy_config_panel.tsx | 14 +- .../public/xy_visualization/xy_suggestions.ts | 3 +- x-pack/plugins/lens/server/plugin.tsx | 2 + 136 files changed, 2123 insertions(+), 1792 deletions(-) rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions}/counter_rate/counter_rate.test.ts (99%) rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions}/counter_rate/index.ts (97%) create mode 100644 x-pack/plugins/lens/common/expressions/datatable/datatable.ts create mode 100644 x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts create mode 100644 x-pack/plugins/lens/common/expressions/datatable/index.ts rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/sorting.test.tsx (100%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/sorting.tsx (98%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/summary.test.ts (98%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/summary.ts (91%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/transpose_helpers.test.ts (99%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/transpose_helpers.ts (95%) rename x-pack/plugins/lens/{public/datatable_visualization => common/expressions/datatable}/utils.ts (80%) rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions/format_column}/format_column.test.ts (98%) rename x-pack/plugins/lens/{public/indexpattern_datasource/format_column.ts => common/expressions/format_column/index.ts} (98%) create mode 100644 x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_chart.ts create mode 100644 x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_grid.ts create mode 100644 x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_legend.ts create mode 100644 x-pack/plugins/lens/common/expressions/heatmap_chart/index.ts create mode 100644 x-pack/plugins/lens/common/expressions/index.ts rename x-pack/plugins/lens/{public/editor_frame_service/merge_tables.ts => common/expressions/merge_tables/index.ts} (84%) rename x-pack/plugins/lens/{public/editor_frame_service => common/expressions/merge_tables}/merge_tables.test.ts (98%) create mode 100644 x-pack/plugins/lens/common/expressions/metric_chart/index.ts create mode 100644 x-pack/plugins/lens/common/expressions/metric_chart/metric_chart.ts rename x-pack/plugins/lens/{public/metric_visualization => common/expressions/metric_chart}/types.ts (100%) create mode 100644 x-pack/plugins/lens/common/expressions/pie_chart/index.ts create mode 100644 x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts rename x-pack/plugins/lens/{public/pie_visualization => common/expressions/pie_chart}/types.ts (89%) create mode 100644 x-pack/plugins/lens/common/expressions/rename_columns/index.ts rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions/rename_columns}/rename_columns.test.ts (96%) rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions/rename_columns}/rename_columns.ts (86%) create mode 100644 x-pack/plugins/lens/common/expressions/time_scale/index.ts rename x-pack/plugins/lens/{public/indexpattern_datasource => common/expressions/time_scale}/time_scale.test.ts (89%) create mode 100644 x-pack/plugins/lens/common/expressions/time_scale/time_scale.ts create mode 100644 x-pack/plugins/lens/common/expressions/time_scale/types.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/fitting_function.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/grid_lines_config.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/index.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/layer_config.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/legend_config.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/series_type.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/tick_labels_config.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts create mode 100644 x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts rename x-pack/plugins/lens/{public/indexpattern_datasource/suffix_formatter.ts => common/suffix_formatter/index.ts} (93%) rename x-pack/plugins/lens/{public/indexpattern_datasource => common/suffix_formatter}/suffix_formatter.test.ts (96%) delete mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/time_scale.ts delete mode 100644 x-pack/plugins/lens/public/shared_components/coloring/types.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/counter_rate.test.ts b/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/counter_rate.test.ts rename to x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts index 4b909489f3236b..3e1a5ad8e39643 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/counter_rate.test.ts +++ b/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { counterRate, CounterRateArgs } from '../counter_rate'; +import { counterRate, CounterRateArgs } from './index'; import { Datatable } from 'src/plugins/expressions/public'; import { functionWrapper } from 'src/plugins/expressions/common/expression_functions/specs/tests/utils'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/index.ts b/x-pack/plugins/lens/common/expressions/counter_rate/index.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/index.ts rename to x-pack/plugins/lens/common/expressions/counter_rate/index.ts index de59597ab6ba38..41f5547dff969e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/counter_rate/index.ts +++ b/x-pack/plugins/lens/common/expressions/counter_rate/index.ts @@ -6,11 +6,14 @@ */ import { i18n } from '@kbn/i18n'; -import { ExpressionFunctionDefinition, Datatable } from 'src/plugins/expressions/public'; import { getBucketIdentifier, buildResultColumns, } from '../../../../../../src/plugins/expressions/common'; +import type { + ExpressionFunctionDefinition, + Datatable, +} from '../../../../../../src/plugins/expressions/common'; export interface CounterRateArgs { by?: string[]; diff --git a/x-pack/plugins/lens/common/expressions/datatable/datatable.ts b/x-pack/plugins/lens/common/expressions/datatable/datatable.ts new file mode 100644 index 00000000000000..d2db63a01793ed --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable.ts @@ -0,0 +1,158 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { cloneDeep } from 'lodash'; +import type { + DatatableColumnMeta, + ExpressionFunctionDefinition, +} from '../../../../../../src/plugins/expressions/common'; +import type { FormatFactory, LensMultiTable } from '../../types'; +import type { ColumnConfigArg } from './datatable_column'; +import { getSortingCriteria } from './sorting'; +import { computeSummaryRowForColumn } from './summary'; +import { transposeTable } from './transpose_helpers'; + +export interface SortingState { + columnId: string | undefined; + direction: 'asc' | 'desc' | 'none'; +} + +export interface DatatableProps { + data: LensMultiTable; + untransposedData?: LensMultiTable; + args: DatatableArgs; +} + +export interface DatatableRender { + type: 'render'; + as: 'lens_datatable_renderer'; + value: DatatableProps; +} + +export interface DatatableArgs { + title: string; + description?: string; + columns: ColumnConfigArg[]; + sortingColumnId: SortingState['columnId']; + sortingDirection: SortingState['direction']; +} + +function isRange(meta: { params?: { id?: string } } | undefined) { + return meta?.params?.id === 'range'; +} + +export const getDatatable = ({ + formatFactory, +}: { + formatFactory: FormatFactory; +}): ExpressionFunctionDefinition< + 'lens_datatable', + LensMultiTable, + DatatableArgs, + DatatableRender +> => ({ + name: 'lens_datatable', + type: 'render', + inputTypes: ['lens_multitable'], + help: i18n.translate('xpack.lens.datatable.expressionHelpLabel', { + defaultMessage: 'Datatable renderer', + }), + args: { + title: { + types: ['string'], + help: i18n.translate('xpack.lens.datatable.titleLabel', { + defaultMessage: 'Title', + }), + }, + description: { + types: ['string'], + help: '', + }, + columns: { + types: ['lens_datatable_column'], + help: '', + multi: true, + }, + sortingColumnId: { + types: ['string'], + help: '', + }, + sortingDirection: { + types: ['string'], + help: '', + }, + }, + fn(data, args, context) { + let untransposedData: LensMultiTable | undefined; + // do the sorting at this level to propagate it also at CSV download + const [firstTable] = Object.values(data.tables); + const [layerId] = Object.keys(context.inspectorAdapters.tables || {}); + const formatters: Record> = {}; + + firstTable.columns.forEach((column) => { + formatters[column.id] = formatFactory(column.meta?.params); + }); + + const hasTransposedColumns = args.columns.some((c) => c.isTransposed); + if (hasTransposedColumns) { + // store original shape of data separately + untransposedData = cloneDeep(data); + // transposes table and args inplace + transposeTable(args, firstTable, formatters); + } + + const { sortingColumnId: sortBy, sortingDirection: sortDirection } = args; + + const columnsReverseLookup = firstTable.columns.reduce< + Record + >((memo, { id, name, meta }, i) => { + memo[id] = { name, index: i, meta }; + return memo; + }, {}); + + const columnsWithSummary = args.columns.filter((c) => c.summaryRow); + for (const column of columnsWithSummary) { + column.summaryRowValue = computeSummaryRowForColumn( + column, + firstTable, + formatters, + formatFactory({ id: 'number' }) + ); + } + + if (sortBy && columnsReverseLookup[sortBy] && sortDirection !== 'none') { + // Sort on raw values for these types, while use the formatted value for the rest + const sortingCriteria = getSortingCriteria( + isRange(columnsReverseLookup[sortBy]?.meta) + ? 'range' + : columnsReverseLookup[sortBy]?.meta?.type, + sortBy, + formatters[sortBy], + sortDirection + ); + // replace the table here + context.inspectorAdapters.tables[layerId].rows = (firstTable.rows || []) + .slice() + .sort(sortingCriteria); + // replace also the local copy + firstTable.rows = context.inspectorAdapters.tables[layerId].rows; + } else { + args.sortingColumnId = undefined; + args.sortingDirection = 'none'; + } + return { + type: 'render', + as: 'lens_datatable_renderer', + value: { + data, + untransposedData, + args, + }, + }; + }, +}); diff --git a/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts new file mode 100644 index 00000000000000..892631c3b0f455 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Direction } from '@elastic/eui'; +import type { + CustomPaletteState, + PaletteOutput, +} from '../../../../../../src/plugins/charts/common'; +import type { + ExpressionFunctionDefinition, + DatatableColumn, +} from '../../../../../../src/plugins/expressions/common'; +import type { CustomPaletteParams } from '../../types'; + +export type LensGridDirection = 'none' | Direction; + +export interface ColumnConfig { + columns: ColumnConfigArg[]; + sortingColumnId: string | undefined; + sortingDirection: LensGridDirection; +} + +export type ColumnConfigArg = Omit & { + type: 'lens_datatable_column'; + palette?: PaletteOutput; + summaryRowValue?: unknown; +}; + +export interface ColumnState { + columnId: string; + width?: number; + hidden?: boolean; + isTransposed?: boolean; + // These flags are necessary to transpose columns and map them back later + // They are set automatically and are not user-editable + transposable?: boolean; + originalColumnId?: string; + originalName?: string; + bucketValues?: Array<{ originalBucketColumn: DatatableColumn; value: unknown }>; + alignment?: 'left' | 'right' | 'center'; + palette?: PaletteOutput; + colorMode?: 'none' | 'cell' | 'text'; + summaryRow?: 'none' | 'sum' | 'avg' | 'count' | 'min' | 'max'; + summaryLabel?: string; +} + +export type DatatableColumnResult = ColumnState & { type: 'lens_datatable_column' }; + +export const datatableColumn: ExpressionFunctionDefinition< + 'lens_datatable_column', + null, + ColumnState, + DatatableColumnResult +> = { + name: 'lens_datatable_column', + aliases: [], + type: 'lens_datatable_column', + help: '', + inputTypes: ['null'], + args: { + columnId: { types: ['string'], help: '' }, + alignment: { types: ['string'], help: '' }, + hidden: { types: ['boolean'], help: '' }, + width: { types: ['number'], help: '' }, + isTransposed: { types: ['boolean'], help: '' }, + transposable: { types: ['boolean'], help: '' }, + colorMode: { types: ['string'], help: '' }, + palette: { + types: ['palette'], + help: '', + }, + summaryRow: { types: ['string'], help: '' }, + summaryLabel: { types: ['string'], help: '' }, + }, + fn: function fn(input: unknown, args: ColumnState) { + return { + type: 'lens_datatable_column', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/datatable/index.ts b/x-pack/plugins/lens/common/expressions/datatable/index.ts new file mode 100644 index 00000000000000..2602aae252ca92 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/datatable/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './datatable_column'; +export * from './datatable'; +export * from './summary'; +export * from './transpose_helpers'; +export * from './utils'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/sorting.test.tsx b/x-pack/plugins/lens/common/expressions/datatable/sorting.test.tsx similarity index 100% rename from x-pack/plugins/lens/public/datatable_visualization/sorting.test.tsx rename to x-pack/plugins/lens/common/expressions/datatable/sorting.test.tsx diff --git a/x-pack/plugins/lens/public/datatable_visualization/sorting.tsx b/x-pack/plugins/lens/common/expressions/datatable/sorting.tsx similarity index 98% rename from x-pack/plugins/lens/public/datatable_visualization/sorting.tsx rename to x-pack/plugins/lens/common/expressions/datatable/sorting.tsx index 0859ab5428c9ef..13ca811b0b0823 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/sorting.tsx +++ b/x-pack/plugins/lens/common/expressions/datatable/sorting.tsx @@ -7,7 +7,7 @@ import ipaddr from 'ipaddr.js'; import type { IPv4, IPv6 } from 'ipaddr.js'; -import { FieldFormat } from 'src/plugins/data/public'; +import type { FieldFormat } from '../../../../../../src/plugins/data/common'; function isIPv6Address(ip: IPv4 | IPv6): ip is IPv6 { return ip.kind() === 'ipv6'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/summary.test.ts b/x-pack/plugins/lens/common/expressions/datatable/summary.test.ts similarity index 98% rename from x-pack/plugins/lens/public/datatable_visualization/summary.test.ts rename to x-pack/plugins/lens/common/expressions/datatable/summary.test.ts index f92c83fbbfdc89..9f8f56cc927683 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/summary.test.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/summary.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IFieldFormat } from 'src/plugins/data/public'; +import { IFieldFormat } from 'src/plugins/data/common'; import { Datatable } from 'src/plugins/expressions'; import { computeSummaryRowForColumn, getFinalSummaryConfiguration } from './summary'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/summary.ts b/x-pack/plugins/lens/common/expressions/datatable/summary.ts similarity index 91% rename from x-pack/plugins/lens/public/datatable_visualization/summary.ts rename to x-pack/plugins/lens/common/expressions/datatable/summary.ts index 6c267445aab761..aceade2a3a5139 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/summary.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/summary.ts @@ -6,11 +6,11 @@ */ import { i18n } from '@kbn/i18n'; -import { FieldFormat } from 'src/plugins/data/public'; -import { Datatable } from 'src/plugins/expressions/public'; -import { ColumnConfigArg } from './datatable_visualization'; +import type { FieldFormat } from '../../../../../../src/plugins/data/common'; +import type { Datatable } from '../../../../../../src/plugins/expressions/common'; +import { ColumnConfigArg } from './datatable_column'; import { getOriginalId } from './transpose_helpers'; -import { isNumericField } from './utils'; +import { isNumericFieldForDatatable } from './utils'; type SummaryRowType = Extract; @@ -19,7 +19,7 @@ export function getFinalSummaryConfiguration( columnArgs: Pick | undefined, table: Datatable | undefined ) { - const isNumeric = isNumericField(table, columnId); + const isNumeric = isNumericFieldForDatatable(table, columnId); const summaryRow = isNumeric ? columnArgs?.summaryRow || 'none' : 'none'; const summaryLabel = columnArgs?.summaryLabel ?? getDefaultSummaryLabel(summaryRow); diff --git a/x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.test.ts b/x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.test.ts similarity index 99% rename from x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.test.ts rename to x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.test.ts index 91559a1778f4f6..7ac6b3d987c842 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.test.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.test.ts @@ -7,8 +7,8 @@ import type { FieldFormat } from 'src/plugins/data/public'; import type { Datatable } from 'src/plugins/expressions'; +import { DatatableArgs } from './datatable'; -import { Args } from './expression'; import { transposeTable } from './transpose_helpers'; describe('transpose_helpes', () => { @@ -59,7 +59,7 @@ describe('transpose_helpes', () => { }; } - function buildArgs(): Args { + function buildArgs(): DatatableArgs { return { title: 'Table', sortingColumnId: undefined, diff --git a/x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.ts b/x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.ts similarity index 95% rename from x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.ts rename to x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.ts index a35edf7499073a..06798413c8f40e 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/transpose_helpers.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/transpose_helpers.ts @@ -5,11 +5,14 @@ * 2.0. */ -import type { FieldFormat } from 'src/plugins/data/public'; -import type { Datatable, DatatableColumn, DatatableRow } from 'src/plugins/expressions'; -import { ColumnConfig } from './components/table_basic'; - -import { Args, ColumnConfigArg } from './expression'; +import type { + Datatable, + DatatableColumn, + DatatableRow, +} from '../../../../../../src/plugins/expressions'; +import type { FieldFormat } from '../../../../../../src/plugins/data/common'; +import type { DatatableArgs } from './datatable'; +import type { ColumnConfig, ColumnConfigArg } from './datatable_column'; const TRANSPOSE_SEPARATOR = '---'; @@ -42,7 +45,7 @@ export function getOriginalId(id: string) { * @param formatters Formatters for all columns to transpose columns by actual display values */ export function transposeTable( - args: Args, + args: DatatableArgs, firstTable: Datatable, formatters: Record ) { @@ -112,7 +115,7 @@ function transposeRows( * grouped by unique value */ function updateColumnArgs( - args: Args, + args: DatatableArgs, bucketsColumnArgs: ColumnConfig['columns'], transposedColumnGroups: Array ) { @@ -150,7 +153,7 @@ function getUniqueValues(table: Datatable, formatter: FieldFormat, columnId: str * @param uniqueValues */ function transposeColumns( - args: Args, + args: DatatableArgs, bucketsColumnArgs: ColumnConfig['columns'], metricColumns: ColumnConfig['columns'], firstTable: Datatable, diff --git a/x-pack/plugins/lens/public/datatable_visualization/utils.ts b/x-pack/plugins/lens/common/expressions/datatable/utils.ts similarity index 80% rename from x-pack/plugins/lens/public/datatable_visualization/utils.ts rename to x-pack/plugins/lens/common/expressions/datatable/utils.ts index 64fdee233e8304..486ec7102e1eba 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/utils.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/utils.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { Datatable } from 'src/plugins/expressions/public'; +import type { Datatable } from '../../../../../../src/plugins/expressions/common'; import { getOriginalId } from './transpose_helpers'; function isValidNumber(value: unknown): boolean { return typeof value === 'number' || value == null; } -export function isNumericField(currentData: Datatable | undefined, accessor: string) { +export function isNumericFieldForDatatable(currentData: Datatable | undefined, accessor: string) { const isNumeric = currentData?.columns.find((col) => col.id === accessor || getOriginalId(col.id) === accessor) ?.meta.type === 'number'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/format_column.test.ts b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/format_column.test.ts rename to x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts index 38643f2dfbda70..4428225b349da5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/format_column.test.ts +++ b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts @@ -7,7 +7,7 @@ import { Datatable, DatatableColumn } from 'src/plugins/expressions/public'; import { functionWrapper } from 'src/plugins/expressions/common/expression_functions/specs/tests/utils'; -import { FormatColumnArgs, formatColumn } from './format_column'; +import { FormatColumnArgs, formatColumn } from './index'; describe('format_column', () => { const fn: (input: Datatable, args: FormatColumnArgs) => Datatable = functionWrapper(formatColumn); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/format_column.ts b/x-pack/plugins/lens/common/expressions/format_column/index.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/format_column.ts rename to x-pack/plugins/lens/common/expressions/format_column/index.ts index 09a4e607a1586f..c874eac1ede1ff 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/format_column.ts +++ b/x-pack/plugins/lens/common/expressions/format_column/index.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { +import type { ExpressionFunctionDefinition, Datatable, DatatableColumn, -} from 'src/plugins/expressions/public'; +} from '../../../../../../src/plugins/expressions/common'; export interface FormatColumnArgs { format: string; diff --git a/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_chart.ts b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_chart.ts new file mode 100644 index 00000000000000..4674879dcac9f8 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_chart.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { PaletteOutput } from '../../../../../../src/plugins/charts/common'; +import type { LensMultiTable, CustomPaletteParams } from '../../types'; +import { HeatmapGridConfigResult, HEATMAP_GRID_FUNCTION } from './heatmap_grid'; +import { HeatmapLegendConfigResult, HEATMAP_LEGEND_FUNCTION } from './heatmap_legend'; + +export const HEATMAP_FUNCTION = 'lens_heatmap'; +export const HEATMAP_FUNCTION_RENDERER = 'lens_heatmap_renderer'; + +export type ChartShapes = 'heatmap'; + +export interface SharedHeatmapLayerState { + shape: ChartShapes; + xAccessor?: string; + yAccessor?: string; + valueAccessor?: string; + legend: HeatmapLegendConfigResult; + gridConfig: HeatmapGridConfigResult; +} + +export type HeatmapLayerState = SharedHeatmapLayerState & { + layerId: string; +}; + +export type HeatmapVisualizationState = HeatmapLayerState & { + // need to store the current accessor to reset the color stops at accessor change + palette?: PaletteOutput & { accessor: string }; +}; + +export type HeatmapExpressionArgs = SharedHeatmapLayerState & { + title?: string; + description?: string; + palette: PaletteOutput; +}; + +export interface HeatmapRender { + type: 'render'; + as: typeof HEATMAP_FUNCTION_RENDERER; + value: HeatmapExpressionProps; +} + +export interface HeatmapExpressionProps { + data: LensMultiTable; + args: HeatmapExpressionArgs; +} + +export const heatmap: ExpressionFunctionDefinition< + typeof HEATMAP_FUNCTION, + LensMultiTable, + HeatmapExpressionArgs, + HeatmapRender +> = { + name: HEATMAP_FUNCTION, + type: 'render', + help: i18n.translate('xpack.lens.heatmap.expressionHelpLabel', { + defaultMessage: 'Heatmap renderer', + }), + args: { + title: { + types: ['string'], + help: i18n.translate('xpack.lens.heatmap.titleLabel', { + defaultMessage: 'Title', + }), + }, + description: { + types: ['string'], + help: '', + }, + xAccessor: { + types: ['string'], + help: '', + }, + yAccessor: { + types: ['string'], + help: '', + }, + valueAccessor: { + types: ['string'], + help: '', + }, + shape: { + types: ['string'], + help: '', + }, + palette: { + default: `{theme "palette" default={system_palette name="default"} }`, + help: '', + types: ['palette'], + }, + legend: { + types: [HEATMAP_LEGEND_FUNCTION], + help: i18n.translate('xpack.lens.heatmapChart.legend.help', { + defaultMessage: 'Configure the chart legend.', + }), + }, + gridConfig: { + types: [HEATMAP_GRID_FUNCTION], + help: i18n.translate('xpack.lens.heatmapChart.gridConfig.help', { + defaultMessage: 'Configure the heatmap layout.', + }), + }, + }, + inputTypes: ['lens_multitable'], + fn(data: LensMultiTable, args: HeatmapExpressionArgs) { + return { + type: 'render', + as: HEATMAP_FUNCTION_RENDERER, + value: { + data, + args, + }, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_grid.ts b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_grid.ts new file mode 100644 index 00000000000000..5fe7f4b8f6c62b --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_grid.ts @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; + +export const HEATMAP_GRID_FUNCTION = 'lens_heatmap_grid'; + +export interface HeatmapGridConfig { + // grid + strokeWidth?: number; + strokeColor?: string; + cellHeight?: number; + cellWidth?: number; + // cells + isCellLabelVisible: boolean; + // Y-axis + isYAxisLabelVisible: boolean; + yAxisLabelWidth?: number; + yAxisLabelColor?: string; + // X-axis + isXAxisLabelVisible: boolean; +} + +export type HeatmapGridConfigResult = HeatmapGridConfig & { type: typeof HEATMAP_GRID_FUNCTION }; + +export const heatmapGridConfig: ExpressionFunctionDefinition< + typeof HEATMAP_GRID_FUNCTION, + null, + HeatmapGridConfig, + HeatmapGridConfigResult +> = { + name: HEATMAP_GRID_FUNCTION, + aliases: [], + type: HEATMAP_GRID_FUNCTION, + help: `Configure the heatmap layout `, + inputTypes: ['null'], + args: { + // grid + strokeWidth: { + types: ['number'], + help: i18n.translate('xpack.lens.heatmapChart.config.strokeWidth.help', { + defaultMessage: 'Specifies the grid stroke width', + }), + required: false, + }, + strokeColor: { + types: ['string'], + help: i18n.translate('xpack.lens.heatmapChart.config.strokeColor.help', { + defaultMessage: 'Specifies the grid stroke color', + }), + required: false, + }, + cellHeight: { + types: ['number'], + help: i18n.translate('xpack.lens.heatmapChart.config.cellHeight.help', { + defaultMessage: 'Specifies the grid cell height', + }), + required: false, + }, + cellWidth: { + types: ['number'], + help: i18n.translate('xpack.lens.heatmapChart.config.cellWidth.help', { + defaultMessage: 'Specifies the grid cell width', + }), + required: false, + }, + // cells + isCellLabelVisible: { + types: ['boolean'], + help: i18n.translate('xpack.lens.heatmapChart.config.isCellLabelVisible.help', { + defaultMessage: 'Specifies whether or not the cell label is visible.', + }), + }, + // Y-axis + isYAxisLabelVisible: { + types: ['boolean'], + help: i18n.translate('xpack.lens.heatmapChart.config.isYAxisLabelVisible.help', { + defaultMessage: 'Specifies whether or not the Y-axis labels are visible.', + }), + }, + yAxisLabelWidth: { + types: ['number'], + help: i18n.translate('xpack.lens.heatmapChart.config.yAxisLabelWidth.help', { + defaultMessage: 'Specifies the width of the Y-axis labels.', + }), + required: false, + }, + yAxisLabelColor: { + types: ['string'], + help: i18n.translate('xpack.lens.heatmapChart.config.yAxisLabelColor.help', { + defaultMessage: 'Specifies the color of the Y-axis labels.', + }), + required: false, + }, + // X-axis + isXAxisLabelVisible: { + types: ['boolean'], + help: i18n.translate('xpack.lens.heatmapChart.config.isXAxisLabelVisible.help', { + defaultMessage: 'Specifies whether or not the X-axis labels are visible.', + }), + }, + }, + fn(input, args) { + return { + type: HEATMAP_GRID_FUNCTION, + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_legend.ts b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_legend.ts new file mode 100644 index 00000000000000..0f553c6cae1f09 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/heatmap_chart/heatmap_legend.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { Position } from '@elastic/charts'; +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; + +export const HEATMAP_LEGEND_FUNCTION = 'lens_heatmap_legendConfig'; + +export interface HeatmapLegendConfig { + /** + * Flag whether the legend should be shown. If there is just a single series, it will be hidden + */ + isVisible: boolean; + /** + * Position of the legend relative to the chart + */ + position: Position; +} + +export type HeatmapLegendConfigResult = HeatmapLegendConfig & { + type: typeof HEATMAP_LEGEND_FUNCTION; +}; + +/** + * TODO check if it's possible to make a shared function + * based on the XY chart + */ +export const heatmapLegendConfig: ExpressionFunctionDefinition< + typeof HEATMAP_LEGEND_FUNCTION, + null, + HeatmapLegendConfig, + HeatmapLegendConfigResult +> = { + name: HEATMAP_LEGEND_FUNCTION, + aliases: [], + type: HEATMAP_LEGEND_FUNCTION, + help: `Configure the heatmap chart's legend`, + inputTypes: ['null'], + args: { + isVisible: { + types: ['boolean'], + help: i18n.translate('xpack.lens.heatmapChart.legend.isVisible.help', { + defaultMessage: 'Specifies whether or not the legend is visible.', + }), + }, + position: { + types: ['string'], + options: [Position.Top, Position.Right, Position.Bottom, Position.Left], + help: i18n.translate('xpack.lens.heatmapChart.legend.position.help', { + defaultMessage: 'Specifies the legend position.', + }), + }, + }, + fn(input, args) { + return { + type: HEATMAP_LEGEND_FUNCTION, + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/heatmap_chart/index.ts b/x-pack/plugins/lens/common/expressions/heatmap_chart/index.ts new file mode 100644 index 00000000000000..96f8c074b1fc42 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/heatmap_chart/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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './heatmap_grid'; +export * from './heatmap_legend'; +export * from './heatmap_chart'; diff --git a/x-pack/plugins/lens/common/expressions/index.ts b/x-pack/plugins/lens/common/expressions/index.ts new file mode 100644 index 00000000000000..70a85f85938e44 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './counter_rate'; +export * from './format_column'; +export * from './rename_columns'; +export * from './merge_tables'; +export * from './time_scale'; +export * from './datatable'; +export * from './heatmap_chart'; +export * from './metric_chart'; +export * from './pie_chart'; +export * from './xy_chart'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/merge_tables.ts b/x-pack/plugins/lens/common/expressions/merge_tables/index.ts similarity index 84% rename from x-pack/plugins/lens/public/editor_frame_service/merge_tables.ts rename to x-pack/plugins/lens/common/expressions/merge_tables/index.ts index cd93392fc712d6..e190da19886df5 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/merge_tables.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/index.ts @@ -6,16 +6,16 @@ */ import { i18n } from '@kbn/i18n'; -import { - ExecutionContext, - Datatable, +import type { ExpressionFunctionDefinition, -} from 'src/plugins/expressions/public'; -import { ExpressionValueSearchContext, search } from '../../../../../src/plugins/data/public'; -const { toAbsoluteDates } = search.aggs; + Datatable, + ExecutionContext, +} from '../../../../../../src/plugins/expressions/common'; +import { toAbsoluteDates } from '../../../../../../src/plugins/data/common'; +import type { ExpressionValueSearchContext } from '../../../../../../src/plugins/data/common'; -import { LensMultiTable } from '../types'; -import { Adapters } from '../../../../../src/plugins/inspector/common'; +import type { LensMultiTable } from '../../types'; +import { Adapters } from '../../../../../../src/plugins/inspector/common'; interface MergeTables { layerIds: string[]; diff --git a/x-pack/plugins/lens/public/editor_frame_service/merge_tables.test.ts b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts similarity index 98% rename from x-pack/plugins/lens/public/editor_frame_service/merge_tables.test.ts rename to x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts index eb381b33655e2e..c883f6b7cb479c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/merge_tables.test.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment'; -import { mergeTables } from './merge_tables'; +import { mergeTables } from './index'; import { ExpressionValueSearchContext } from 'src/plugins/data/public'; import { Datatable, diff --git a/x-pack/plugins/lens/common/expressions/metric_chart/index.ts b/x-pack/plugins/lens/common/expressions/metric_chart/index.ts new file mode 100644 index 00000000000000..40bd4f38864551 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/metric_chart/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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './types'; +export * from './metric_chart'; diff --git a/x-pack/plugins/lens/common/expressions/metric_chart/metric_chart.ts b/x-pack/plugins/lens/common/expressions/metric_chart/metric_chart.ts new file mode 100644 index 00000000000000..53ed7c8da32eb6 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/metric_chart/metric_chart.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { LensMultiTable } from '../../types'; +import type { MetricConfig } from './types'; + +export interface MetricChartProps { + data: LensMultiTable; + args: MetricConfig; +} + +export interface MetricRender { + type: 'render'; + as: 'lens_metric_chart_renderer'; + value: MetricChartProps; +} + +export const metricChart: ExpressionFunctionDefinition< + 'lens_metric_chart', + LensMultiTable, + Omit, + MetricRender +> = { + name: 'lens_metric_chart', + type: 'render', + help: 'A metric chart', + args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, + metricTitle: { + types: ['string'], + help: 'The title of the metric shown.', + }, + accessor: { + types: ['string'], + help: 'The column whose value is being displayed', + }, + mode: { + types: ['string'], + options: ['reduced', 'full'], + default: 'full', + help: + 'The display mode of the chart - reduced will only show the metric itself without min size', + }, + }, + inputTypes: ['lens_multitable'], + fn(data, args) { + return { + type: 'render', + as: 'lens_metric_chart_renderer', + value: { + data, + args, + }, + } as MetricRender; + }, +}; diff --git a/x-pack/plugins/lens/public/metric_visualization/types.ts b/x-pack/plugins/lens/common/expressions/metric_chart/types.ts similarity index 100% rename from x-pack/plugins/lens/public/metric_visualization/types.ts rename to x-pack/plugins/lens/common/expressions/metric_chart/types.ts diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/index.ts b/x-pack/plugins/lens/common/expressions/pie_chart/index.ts new file mode 100644 index 00000000000000..e82294f8aff256 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/pie_chart/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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './types'; +export * from './pie_chart'; diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts new file mode 100644 index 00000000000000..b298f1d8b3a806 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Position } from '@elastic/charts'; +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { LensMultiTable } from '../../types'; +import type { PieExpressionProps, PieExpressionArgs } from './types'; + +export interface PieRender { + type: 'render'; + as: 'lens_pie_renderer'; + value: PieExpressionProps; +} + +export const pie: ExpressionFunctionDefinition< + 'lens_pie', + LensMultiTable, + PieExpressionArgs, + PieRender +> = { + name: 'lens_pie', + type: 'render', + help: i18n.translate('xpack.lens.pie.expressionHelpLabel', { + defaultMessage: 'Pie renderer', + }), + args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, + groups: { + types: ['string'], + multi: true, + help: '', + }, + metric: { + types: ['string'], + help: '', + }, + shape: { + types: ['string'], + options: ['pie', 'donut', 'treemap'], + help: '', + }, + hideLabels: { + types: ['boolean'], + help: '', + }, + numberDisplay: { + types: ['string'], + options: ['hidden', 'percent', 'value'], + help: '', + }, + categoryDisplay: { + types: ['string'], + options: ['default', 'inside', 'hide'], + help: '', + }, + legendDisplay: { + types: ['string'], + options: ['default', 'show', 'hide'], + help: '', + }, + nestedLegend: { + types: ['boolean'], + help: '', + }, + legendPosition: { + types: ['string'], + options: [Position.Top, Position.Right, Position.Bottom, Position.Left], + help: '', + }, + percentDecimals: { + types: ['number'], + help: '', + }, + palette: { + default: `{theme "palette" default={system_palette name="default"} }`, + help: '', + types: ['palette'], + }, + }, + inputTypes: ['lens_multitable'], + fn(data: LensMultiTable, args: PieExpressionArgs) { + return { + type: 'render', + as: 'lens_pie_renderer', + value: { + data, + args, + }, + }; + }, +}; diff --git a/x-pack/plugins/lens/public/pie_visualization/types.ts b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts similarity index 89% rename from x-pack/plugins/lens/public/pie_visualization/types.ts rename to x-pack/plugins/lens/common/expressions/pie_chart/types.ts index c03ab15ecc2907..e3772723229507 100644 --- a/x-pack/plugins/lens/public/pie_visualization/types.ts +++ b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { PaletteOutput } from 'src/plugins/charts/public'; -import { LensMultiTable } from '../types'; +import type { PaletteOutput } from '../../../../../../src/plugins/charts/common'; +import type { LensMultiTable } from '../../types'; export interface SharedPieLayerState { groups: string[]; diff --git a/x-pack/plugins/lens/common/expressions/rename_columns/index.ts b/x-pack/plugins/lens/common/expressions/rename_columns/index.ts new file mode 100644 index 00000000000000..4cb8ff75f486de --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/rename_columns/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './rename_columns'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts b/x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.test.ts similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts rename to x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.test.ts index 5654a599c5e27b..f3db64c1d2257a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts +++ b/x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.test.ts @@ -6,8 +6,8 @@ */ import { renameColumns } from './rename_columns'; -import { Datatable } from '../../../../../src/plugins/expressions/public'; -import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; +import { Datatable } from '../../../../../../src/plugins/expressions/common'; +import { createMockExecutionContext } from '../../../../../../src/plugins/expressions/common/mocks'; describe('rename_columns', () => { it('should rename columns of a given datatable', () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts b/x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.ts similarity index 86% rename from x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts rename to x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.ts index a16756126c030c..517bd683d80aed 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts +++ b/x-pack/plugins/lens/common/expressions/rename_columns/rename_columns.ts @@ -6,14 +6,20 @@ */ import { i18n } from '@kbn/i18n'; -import { ExpressionFunctionDefinition, Datatable, DatatableColumn } from 'src/plugins/expressions'; -import { IndexPatternColumn } from './operations'; +import { + ExpressionFunctionDefinition, + Datatable, + DatatableColumn, +} from '../../../../../../src/plugins/expressions/common'; interface RemapArgs { idMap: string; } -export type OriginalColumn = { id: string } & IndexPatternColumn; +type OriginalColumn = { id: string; label: string } & ( + | { operationType: 'date_histogram'; sourceField: string } + | { operationType: string; sourceField: never } +); export const renameColumns: ExpressionFunctionDefinition< 'lens_rename_columns', @@ -75,7 +81,7 @@ export const renameColumns: ExpressionFunctionDefinition< }; function getColumnName(originalColumn: OriginalColumn, newColumn: DatatableColumn) { - if (originalColumn && originalColumn.operationType === 'date_histogram') { + if (originalColumn?.operationType === 'date_histogram') { const fieldName = originalColumn.sourceField; // HACK: This is a hack, and introduces some fragility into diff --git a/x-pack/plugins/lens/common/expressions/time_scale/index.ts b/x-pack/plugins/lens/common/expressions/time_scale/index.ts new file mode 100644 index 00000000000000..92fec01a9ecbc4 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/time_scale/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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './time_scale'; +export * from './types'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_scale.test.ts b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts similarity index 89% rename from x-pack/plugins/lens/public/indexpattern_datasource/time_scale.test.ts rename to x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts index 34579927cfe195..c0a5c4bf1e1ec9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/time_scale.test.ts +++ b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts @@ -7,14 +7,25 @@ import moment from 'moment'; import { Datatable } from 'src/plugins/expressions/public'; -import { DataPublicPluginStart, TimeRange } from 'src/plugins/data/public'; -import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks'; +import { TimeRange } from 'src/plugins/data/public'; import { functionWrapper } from 'src/plugins/expressions/common/expression_functions/specs/tests/utils'; -import { getTimeScaleFunction, TimeScaleArgs } from './time_scale'; + +// mock the specific inner variable: +// there are intra dependencies in the data plugin we might break trying to mock the whole thing +jest.mock('../../../../../../src/plugins/data/common/query/timefilter/get_time', () => { + const localMoment = jest.requireActual('moment'); + return { + calculateBounds: jest.fn(({ from, to }) => ({ + min: localMoment(from), + max: localMoment(to), + })), + }; +}); + +import { timeScale, TimeScaleArgs } from './time_scale'; describe('time_scale', () => { - let timeScale: (input: Datatable, args: TimeScaleArgs) => Promise; - let dataMock: jest.Mocked; + let timeScaleWrapped: (input: Datatable, args: TimeScaleArgs) => Promise; const emptyTable: Datatable = { type: 'datatable', @@ -61,7 +72,6 @@ describe('time_scale', () => { } beforeEach(() => { - dataMock = dataPluginMock.createStartContract(); setDateHistogramMeta({ timeZone: 'UTC', timeRange: { @@ -70,17 +80,11 @@ describe('time_scale', () => { }, interval: '1d', }); - (dataMock.query.timefilter.timefilter.calculateBounds as jest.Mock).mockImplementation( - ({ from, to }) => ({ - min: moment(from), - max: moment(to), - }) - ); - timeScale = functionWrapper(getTimeScaleFunction(dataMock)); + timeScaleWrapped = functionWrapper(timeScale); }); it('should apply time scale factor to each row', async () => { - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -115,7 +119,7 @@ describe('time_scale', () => { }); it('should skip gaps in the data', async () => { - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -163,7 +167,7 @@ describe('time_scale', () => { }, ], }; - const result = await timeScale(mismatchedTable, { + const result = await timeScaleWrapped(mismatchedTable, { ...defaultArgs, inputColumnId: 'nonexistent', }); @@ -180,7 +184,7 @@ describe('time_scale', () => { }, interval: '1h', }); - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -220,7 +224,7 @@ describe('time_scale', () => { }, interval: '3h', }); - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -262,7 +266,7 @@ describe('time_scale', () => { }, interval: '1d', }); - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -307,7 +311,7 @@ describe('time_scale', () => { }, interval: '1d', }); - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ @@ -347,7 +351,7 @@ describe('time_scale', () => { }, interval: '1y', }); - const result = await timeScale( + const result = await timeScaleWrapped( { ...emptyTable, rows: [ diff --git a/x-pack/plugins/lens/common/expressions/time_scale/time_scale.ts b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.ts new file mode 100644 index 00000000000000..fc2023ca4d599f --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment-timezone'; +import { i18n } from '@kbn/i18n'; +import type { + ExpressionFunctionDefinition, + Datatable, +} from '../../../../../../src/plugins/expressions/common'; +import { + getDateHistogramMetaDataByDatatableColumn, + parseInterval, + calculateBounds, +} from '../../../../../../src/plugins/data/common'; +import { buildResultColumns } from '../../../../../../src/plugins/expressions/common'; +import type { TimeScaleUnit } from './types'; + +export interface TimeScaleArgs { + dateColumnId: string; + inputColumnId: string; + outputColumnId: string; + targetUnit: TimeScaleUnit; + outputColumnName?: string; +} + +const unitInMs: Record = { + s: 1000, + m: 1000 * 60, + h: 1000 * 60 * 60, + d: 1000 * 60 * 60 * 24, +}; + +export const timeScale: ExpressionFunctionDefinition< + 'lens_time_scale', + Datatable, + TimeScaleArgs, + Promise +> = { + name: 'lens_time_scale', + type: 'datatable', + help: '', + args: { + dateColumnId: { + types: ['string'], + help: '', + required: true, + }, + inputColumnId: { + types: ['string'], + help: '', + required: true, + }, + outputColumnId: { + types: ['string'], + help: '', + required: true, + }, + outputColumnName: { + types: ['string'], + help: '', + }, + targetUnit: { + types: ['string'], + options: ['s', 'm', 'h', 'd'], + help: '', + required: true, + }, + }, + inputTypes: ['datatable'], + async fn( + input, + { dateColumnId, inputColumnId, outputColumnId, outputColumnName, targetUnit }: TimeScaleArgs + ) { + const dateColumnDefinition = input.columns.find((column) => column.id === dateColumnId); + + if (!dateColumnDefinition) { + throw new Error( + i18n.translate('xpack.lens.functions.timeScale.dateColumnMissingMessage', { + defaultMessage: 'Specified dateColumnId {columnId} does not exist.', + values: { + columnId: dateColumnId, + }, + }) + ); + } + + const resultColumns = buildResultColumns( + input, + outputColumnId, + inputColumnId, + outputColumnName, + { allowColumnOverwrite: true } + ); + + if (!resultColumns) { + return input; + } + + const targetUnitInMs = unitInMs[targetUnit]; + const timeInfo = getDateHistogramMetaDataByDatatableColumn(dateColumnDefinition); + const intervalDuration = timeInfo?.interval && parseInterval(timeInfo.interval); + + if (!timeInfo || !intervalDuration) { + throw new Error( + i18n.translate('xpack.lens.functions.timeScale.timeInfoMissingMessage', { + defaultMessage: 'Could not fetch date histogram information', + }) + ); + } + // the datemath plugin always parses dates by using the current default moment time zone. + // to use the configured time zone, we are switching just for the bounds calculation. + const defaultTimezone = moment().zoneName(); + moment.tz.setDefault(timeInfo.timeZone); + + const timeBounds = timeInfo.timeRange && calculateBounds(timeInfo.timeRange); + + const result = { + ...input, + columns: resultColumns, + rows: input.rows.map((row) => { + const newRow = { ...row }; + + let startOfBucket = moment(row[dateColumnId]); + let endOfBucket = startOfBucket.clone().add(intervalDuration); + if (timeBounds && timeBounds.min) { + startOfBucket = moment.max(startOfBucket, timeBounds.min); + } + if (timeBounds && timeBounds.max) { + endOfBucket = moment.min(endOfBucket, timeBounds.max); + } + const bucketSize = endOfBucket.diff(startOfBucket); + const factor = bucketSize / targetUnitInMs; + + const currentValue = newRow[inputColumnId]; + if (currentValue != null) { + newRow[outputColumnId] = Number(currentValue) / factor; + } + + return newRow; + }), + }; + // reset default moment timezone + moment.tz.setDefault(defaultTimezone); + + return result; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/time_scale/types.ts b/x-pack/plugins/lens/common/expressions/time_scale/types.ts new file mode 100644 index 00000000000000..4ee00ce53e68ba --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/time_scale/types.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type TimeScaleUnit = 's' | 'm' | 'h' | 'd'; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts new file mode 100644 index 00000000000000..9a9273e43f6f1c --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts @@ -0,0 +1,171 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import type { + ArgumentType, + ExpressionFunctionDefinition, +} from '../../../../../../src/plugins/expressions/common'; + +export interface AxesSettingsConfig { + x: boolean; + yLeft: boolean; + yRight: boolean; +} + +export interface AxisExtentConfig { + mode: 'full' | 'dataBounds' | 'custom'; + lowerBound?: number; + upperBound?: number; +} + +interface AxisConfig { + title: string; + hide?: boolean; +} + +export type YAxisMode = 'auto' | 'left' | 'right'; + +export interface YConfig { + forAccessor: string; + axisMode?: YAxisMode; + color?: string; +} + +export type AxisTitlesVisibilityConfigResult = AxesSettingsConfig & { + type: 'lens_xy_axisTitlesVisibilityConfig'; +}; + +export const axisTitlesVisibilityConfig: ExpressionFunctionDefinition< + 'lens_xy_axisTitlesVisibilityConfig', + null, + AxesSettingsConfig, + AxisTitlesVisibilityConfigResult +> = { + name: 'lens_xy_axisTitlesVisibilityConfig', + aliases: [], + type: 'lens_xy_axisTitlesVisibilityConfig', + help: `Configure the xy chart's axis titles appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.xAxisTitle.help', { + defaultMessage: 'Specifies whether or not the title of the x-axis are visible.', + }), + }, + yLeft: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yLeftAxisTitle.help', { + defaultMessage: 'Specifies whether or not the title of the left y-axis are visible.', + }), + }, + yRight: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yRightAxisTitle.help', { + defaultMessage: 'Specifies whether or not the title of the right y-axis are visible.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsConfig) { + return { + type: 'lens_xy_axisTitlesVisibilityConfig', + ...args, + }; + }, +}; + +export type AxisExtentConfigResult = AxisExtentConfig & { type: 'lens_xy_axisExtentConfig' }; + +export const axisExtentConfig: ExpressionFunctionDefinition< + 'lens_xy_axisExtentConfig', + null, + AxisExtentConfig, + AxisExtentConfigResult +> = { + name: 'lens_xy_axisExtentConfig', + aliases: [], + type: 'lens_xy_axisExtentConfig', + help: `Configure the xy chart's axis extents`, + inputTypes: ['null'], + args: { + mode: { + types: ['string'], + options: ['full', 'dataBounds', 'custom'], + help: i18n.translate('xpack.lens.xyChart.extentMode.help', { + defaultMessage: 'The extent mode', + }), + }, + lowerBound: { + types: ['number'], + help: i18n.translate('xpack.lens.xyChart.extentMode.help', { + defaultMessage: 'The extent mode', + }), + }, + upperBound: { + types: ['number'], + help: i18n.translate('xpack.lens.xyChart.extentMode.help', { + defaultMessage: 'The extent mode', + }), + }, + }, + fn: function fn(input: unknown, args: AxisExtentConfig) { + return { + type: 'lens_xy_axisExtentConfig', + ...args, + }; + }, +}; + +export const axisConfig: { [key in keyof AxisConfig]: ArgumentType } = { + title: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.title.help', { + defaultMessage: 'The axis title', + }), + }, + hide: { + types: ['boolean'], + default: false, + help: 'Show / hide axis', + }, +}; + +export type YConfigResult = YConfig & { type: 'lens_xy_yConfig' }; + +export const yAxisConfig: ExpressionFunctionDefinition< + 'lens_xy_yConfig', + null, + YConfig, + YConfigResult +> = { + name: 'lens_xy_yConfig', + aliases: [], + type: 'lens_xy_yConfig', + help: `Configure the behavior of a xy chart's y axis metric`, + inputTypes: ['null'], + args: { + forAccessor: { + types: ['string'], + help: 'The accessor this configuration is for', + }, + axisMode: { + types: ['string'], + options: ['auto', 'left', 'right'], + help: 'The axis mode of the metric', + }, + color: { + types: ['string'], + help: 'The color of the series', + }, + }, + fn: function fn(input: unknown, args: YConfig) { + return { + type: 'lens_xy_yConfig', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/fitting_function.ts b/x-pack/plugins/lens/common/expressions/xy_chart/fitting_function.ts new file mode 100644 index 00000000000000..0cfea62d578d70 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/fitting_function.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export type FittingFunction = typeof fittingFunctionDefinitions[number]['id']; + +export const fittingFunctionDefinitions = [ + { + id: 'None', + title: i18n.translate('xpack.lens.fittingFunctionsTitle.none', { + defaultMessage: 'Hide', + }), + description: i18n.translate('xpack.lens.fittingFunctionsDescription.none', { + defaultMessage: 'Do not fill gaps', + }), + }, + { + id: 'Zero', + title: i18n.translate('xpack.lens.fittingFunctionsTitle.zero', { + defaultMessage: 'Zero', + }), + description: i18n.translate('xpack.lens.fittingFunctionsDescription.zero', { + defaultMessage: 'Fill gaps with zeros', + }), + }, + { + id: 'Linear', + title: i18n.translate('xpack.lens.fittingFunctionsTitle.linear', { + defaultMessage: 'Linear', + }), + description: i18n.translate('xpack.lens.fittingFunctionsDescription.linear', { + defaultMessage: 'Fill gaps with a line', + }), + }, + { + id: 'Carry', + title: i18n.translate('xpack.lens.fittingFunctionsTitle.carry', { + defaultMessage: 'Last', + }), + description: i18n.translate('xpack.lens.fittingFunctionsDescription.carry', { + defaultMessage: 'Fill gaps with the last value', + }), + }, + { + id: 'Lookahead', + title: i18n.translate('xpack.lens.fittingFunctionsTitle.lookahead', { + defaultMessage: 'Next', + }), + description: i18n.translate('xpack.lens.fittingFunctionsDescription.lookahead', { + defaultMessage: 'Fill gaps with the next value', + }), + }, +] as const; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/grid_lines_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/grid_lines_config.ts new file mode 100644 index 00000000000000..6338e9f039937f --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/grid_lines_config.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { AxesSettingsConfig } from './axis_config'; + +export type GridlinesConfigResult = AxesSettingsConfig & { type: 'lens_xy_gridlinesConfig' }; + +export const gridlinesConfig: ExpressionFunctionDefinition< + 'lens_xy_gridlinesConfig', + null, + AxesSettingsConfig, + GridlinesConfigResult +> = { + name: 'lens_xy_gridlinesConfig', + aliases: [], + type: 'lens_xy_gridlinesConfig', + help: `Configure the xy chart's gridlines appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.xAxisGridlines.help', { + defaultMessage: 'Specifies whether or not the gridlines of the x-axis are visible.', + }), + }, + yLeft: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yLeftAxisgridlines.help', { + defaultMessage: 'Specifies whether or not the gridlines of the left y-axis are visible.', + }), + }, + yRight: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yRightAxisgridlines.help', { + defaultMessage: 'Specifies whether or not the gridlines of the right y-axis are visible.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsConfig) { + return { + type: 'lens_xy_gridlinesConfig', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/index.ts b/x-pack/plugins/lens/common/expressions/xy_chart/index.ts new file mode 100644 index 00000000000000..4d1125fa459a39 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './axis_config'; +export * from './fitting_function'; +export * from './grid_lines_config'; +export * from './layer_config'; +export * from './legend_config'; +export * from './series_type'; +export * from './tick_labels_config'; +export * from './xy_args'; +export * from './xy_chart'; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/layer_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/layer_config.ts new file mode 100644 index 00000000000000..f3baf242425f5d --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/layer_config.ts @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PaletteOutput } from '../../../../../../src/plugins/charts/common'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import { axisConfig, YConfig } from './axis_config'; +import type { SeriesType } from './series_type'; + +export interface XYLayerConfig { + hide?: boolean; + layerId: string; + xAccessor?: string; + accessors: string[]; + yConfig?: YConfig[]; + seriesType: SeriesType; + splitAccessor?: string; + palette?: PaletteOutput; +} + +export interface ValidLayer extends XYLayerConfig { + xAccessor: NonNullable; +} + +export type LayerArgs = XYLayerConfig & { + columnToLabel?: string; // Actually a JSON key-value pair + yScaleType: 'time' | 'linear' | 'log' | 'sqrt'; + xScaleType: 'time' | 'linear' | 'ordinal'; + isHistogram: boolean; + // palette will always be set on the expression + palette: PaletteOutput; +}; + +export type LayerConfigResult = LayerArgs & { type: 'lens_xy_layer' }; + +export const layerConfig: ExpressionFunctionDefinition< + 'lens_xy_layer', + null, + LayerArgs, + LayerConfigResult +> = { + name: 'lens_xy_layer', + aliases: [], + type: 'lens_xy_layer', + help: `Configure a layer in the xy chart`, + inputTypes: ['null'], + args: { + ...axisConfig, + layerId: { + types: ['string'], + help: '', + }, + xAccessor: { + types: ['string'], + help: '', + }, + seriesType: { + types: ['string'], + options: [ + 'bar', + 'line', + 'area', + 'bar_stacked', + 'area_stacked', + 'bar_percentage_stacked', + 'area_percentage_stacked', + ], + help: 'The type of chart to display.', + }, + xScaleType: { + options: ['ordinal', 'linear', 'time'], + help: 'The scale type of the x axis', + default: 'ordinal', + }, + isHistogram: { + types: ['boolean'], + default: false, + help: 'Whether to layout the chart as a histogram', + }, + yScaleType: { + options: ['log', 'sqrt', 'linear', 'time'], + help: 'The scale type of the y axes', + default: 'linear', + }, + splitAccessor: { + types: ['string'], + help: 'The column to split by', + multi: false, + }, + accessors: { + types: ['string'], + help: 'The columns to display on the y axis.', + multi: true, + }, + yConfig: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + types: ['lens_xy_yConfig' as any], + help: 'Additional configuration for y axes', + multi: true, + }, + columnToLabel: { + types: ['string'], + help: 'JSON key-value pairs of column ID to label', + }, + palette: { + default: `{theme "palette" default={system_palette name="default"} }`, + help: '', + types: ['palette'], + }, + }, + fn: function fn(input: unknown, args: LayerArgs) { + return { + type: 'lens_xy_layer', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/legend_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/legend_config.ts new file mode 100644 index 00000000000000..e228039b53ef6a --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/legend_config.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { HorizontalAlignment, Position, VerticalAlignment } from '@elastic/charts'; +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; + +export interface LegendConfig { + /** + * Flag whether the legend should be shown. If there is just a single series, it will be hidden + */ + isVisible: boolean; + /** + * Position of the legend relative to the chart + */ + position: Position; + /** + * Flag whether the legend should be shown even with just a single series + */ + showSingleSeries?: boolean; + /** + * Flag whether the legend is inside the chart + */ + isInside?: boolean; + /** + * Horizontal Alignment of the legend when it is set inside chart + */ + horizontalAlignment?: HorizontalAlignment; + /** + * Vertical Alignment of the legend when it is set inside chart + */ + verticalAlignment?: VerticalAlignment; + /** + * Number of columns when legend is set inside chart + */ + floatingColumns?: number; +} + +export type LegendConfigResult = LegendConfig & { type: 'lens_xy_legendConfig' }; + +export const legendConfig: ExpressionFunctionDefinition< + 'lens_xy_legendConfig', + null, + LegendConfig, + LegendConfigResult +> = { + name: 'lens_xy_legendConfig', + aliases: [], + type: 'lens_xy_legendConfig', + help: `Configure the xy chart's legend`, + inputTypes: ['null'], + args: { + isVisible: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.isVisible.help', { + defaultMessage: 'Specifies whether or not the legend is visible.', + }), + }, + position: { + types: ['string'], + options: [Position.Top, Position.Right, Position.Bottom, Position.Left], + help: i18n.translate('xpack.lens.xyChart.position.help', { + defaultMessage: 'Specifies the legend position.', + }), + }, + showSingleSeries: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.showSingleSeries.help', { + defaultMessage: 'Specifies whether a legend with just a single entry should be shown', + }), + }, + isInside: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.isInside.help', { + defaultMessage: 'Specifies whether a legend is inside the chart', + }), + }, + horizontalAlignment: { + types: ['string'], + options: [HorizontalAlignment.Right, HorizontalAlignment.Left], + help: i18n.translate('xpack.lens.xyChart.horizontalAlignment.help', { + defaultMessage: + 'Specifies the horizontal alignment of the legend when it is displayed inside chart.', + }), + }, + verticalAlignment: { + types: ['string'], + options: [VerticalAlignment.Top, VerticalAlignment.Bottom], + help: i18n.translate('xpack.lens.xyChart.verticalAlignment.help', { + defaultMessage: + 'Specifies the vertical alignment of the legend when it is displayed inside chart.', + }), + }, + floatingColumns: { + types: ['number'], + help: i18n.translate('xpack.lens.xyChart.floatingColumns.help', { + defaultMessage: 'Specifies the number of columns when legend is displayed inside chart.', + }), + }, + }, + fn: function fn(input: unknown, args: LegendConfig) { + return { + type: 'lens_xy_legendConfig', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/series_type.ts b/x-pack/plugins/lens/common/expressions/xy_chart/series_type.ts new file mode 100644 index 00000000000000..f9a375b8b47a11 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/series_type.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type SeriesType = + | 'bar' + | 'bar_horizontal' + | 'line' + | 'area' + | 'bar_stacked' + | 'bar_percentage_stacked' + | 'bar_horizontal_stacked' + | 'bar_horizontal_percentage_stacked' + | 'area_stacked' + | 'area_percentage_stacked'; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/tick_labels_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/tick_labels_config.ts new file mode 100644 index 00000000000000..4af78d83557864 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/tick_labels_config.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { AxesSettingsConfig } from './axis_config'; + +export type TickLabelsConfigResult = AxesSettingsConfig & { type: 'lens_xy_tickLabelsConfig' }; + +export const tickLabelsConfig: ExpressionFunctionDefinition< + 'lens_xy_tickLabelsConfig', + null, + AxesSettingsConfig, + TickLabelsConfigResult +> = { + name: 'lens_xy_tickLabelsConfig', + aliases: [], + type: 'lens_xy_tickLabelsConfig', + help: `Configure the xy chart's tick labels appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.xAxisTickLabels.help', { + defaultMessage: 'Specifies whether or not the tick labels of the x-axis are visible.', + }), + }, + yLeft: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yLeftAxisTickLabels.help', { + defaultMessage: 'Specifies whether or not the tick labels of the left y-axis are visible.', + }), + }, + yRight: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yRightAxisTickLabels.help', { + defaultMessage: 'Specifies whether or not the tick labels of the right y-axis are visible.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsConfig) { + return { + type: 'lens_xy_tickLabelsConfig', + ...args, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts new file mode 100644 index 00000000000000..3fcf2a187464d1 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AxisExtentConfigResult, AxisTitlesVisibilityConfigResult } from './axis_config'; +import type { FittingFunction } from './fitting_function'; +import type { GridlinesConfigResult } from './grid_lines_config'; +import type { LayerArgs } from './layer_config'; +import type { LegendConfigResult } from './legend_config'; +import type { TickLabelsConfigResult } from './tick_labels_config'; + +export type ValueLabelConfig = 'hide' | 'inside' | 'outside'; + +export type XYCurveType = 'LINEAR' | 'CURVE_MONOTONE_X'; + +// Arguments to XY chart expression, with computed properties +export interface XYArgs { + title?: string; + description?: string; + xTitle: string; + yTitle: string; + yRightTitle: string; + yLeftExtent: AxisExtentConfigResult; + yRightExtent: AxisExtentConfigResult; + legend: LegendConfigResult; + valueLabels: ValueLabelConfig; + layers: LayerArgs[]; + fittingFunction?: FittingFunction; + axisTitlesVisibilitySettings?: AxisTitlesVisibilityConfigResult; + tickLabelsVisibilitySettings?: TickLabelsConfigResult; + gridlinesVisibilitySettings?: GridlinesConfigResult; + curveType?: XYCurveType; + fillOpacity?: number; + hideEndzones?: boolean; + valuesInLegend?: boolean; +} diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts new file mode 100644 index 00000000000000..7fa26f4a2c25d3 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; +import type { ExpressionValueSearchContext } from '../../../../../../src/plugins/data/common'; +import type { LensMultiTable } from '../../types'; +import type { XYArgs } from './xy_args'; +import { fittingFunctionDefinitions } from './fitting_function'; + +export interface XYChartProps { + data: LensMultiTable; + args: XYArgs; +} + +export interface XYRender { + type: 'render'; + as: 'lens_xy_chart_renderer'; + value: XYChartProps; +} + +export const xyChart: ExpressionFunctionDefinition< + 'lens_xy_chart', + LensMultiTable | ExpressionValueSearchContext | null, + XYArgs, + XYRender +> = { + name: 'lens_xy_chart', + type: 'render', + inputTypes: ['lens_multitable', 'kibana_context', 'null'], + help: i18n.translate('xpack.lens.xyChart.help', { + defaultMessage: 'An X/Y chart', + }), + args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, + xTitle: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.xTitle.help', { + defaultMessage: 'X axis title', + }), + }, + yTitle: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.yLeftTitle.help', { + defaultMessage: 'Y left axis title', + }), + }, + yRightTitle: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.yRightTitle.help', { + defaultMessage: 'Y right axis title', + }), + }, + yLeftExtent: { + types: ['lens_xy_axisExtentConfig'], + help: i18n.translate('xpack.lens.xyChart.yLeftExtent.help', { + defaultMessage: 'Y left axis extents', + }), + }, + yRightExtent: { + types: ['lens_xy_axisExtentConfig'], + help: i18n.translate('xpack.lens.xyChart.yRightExtent.help', { + defaultMessage: 'Y right axis extents', + }), + }, + legend: { + types: ['lens_xy_legendConfig'], + help: i18n.translate('xpack.lens.xyChart.legend.help', { + defaultMessage: 'Configure the chart legend.', + }), + }, + fittingFunction: { + types: ['string'], + options: [...fittingFunctionDefinitions.map(({ id }) => id)], + help: i18n.translate('xpack.lens.xyChart.fittingFunction.help', { + defaultMessage: 'Define how missing values are treated', + }), + }, + valueLabels: { + types: ['string'], + options: ['hide', 'inside'], + help: '', + }, + tickLabelsVisibilitySettings: { + types: ['lens_xy_tickLabelsConfig'], + help: i18n.translate('xpack.lens.xyChart.tickLabelsSettings.help', { + defaultMessage: 'Show x and y axes tick labels', + }), + }, + gridlinesVisibilitySettings: { + types: ['lens_xy_gridlinesConfig'], + help: i18n.translate('xpack.lens.xyChart.gridlinesSettings.help', { + defaultMessage: 'Show x and y axes gridlines', + }), + }, + axisTitlesVisibilitySettings: { + types: ['lens_xy_axisTitlesVisibilityConfig'], + help: i18n.translate('xpack.lens.xyChart.axisTitlesSettings.help', { + defaultMessage: 'Show x and y axes titles', + }), + }, + layers: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + types: ['lens_xy_layer'] as any, + help: 'Layers of visual series', + multi: true, + }, + curveType: { + types: ['string'], + options: ['LINEAR', 'CURVE_MONOTONE_X'], + help: i18n.translate('xpack.lens.xyChart.curveType.help', { + defaultMessage: 'Define how curve type is rendered for a line chart', + }), + }, + fillOpacity: { + types: ['number'], + help: i18n.translate('xpack.lens.xyChart.fillOpacity.help', { + defaultMessage: 'Define the area chart fill opacity', + }), + }, + hideEndzones: { + types: ['boolean'], + default: false, + help: i18n.translate('xpack.lens.xyChart.hideEndzones.help', { + defaultMessage: 'Hide endzone markers for partial data', + }), + }, + valuesInLegend: { + types: ['boolean'], + default: false, + help: i18n.translate('xpack.lens.xyChart.valuesInLegend.help', { + defaultMessage: 'Show values in legend', + }), + }, + }, + fn(data: LensMultiTable, args: XYArgs) { + return { + type: 'render', + as: 'lens_xy_chart_renderer', + value: { + data, + args, + }, + }; + }, +}; diff --git a/x-pack/plugins/lens/common/index.ts b/x-pack/plugins/lens/common/index.ts index 25a96d764bb283..42e673058f1dbf 100644 --- a/x-pack/plugins/lens/common/index.ts +++ b/x-pack/plugins/lens/common/index.ts @@ -8,3 +8,6 @@ export * from './api'; export * from './constants'; export * from './types'; + +// Note: do not import the expression folder here or the page bundle will be bloated with all +// the package diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.ts b/x-pack/plugins/lens/common/suffix_formatter/index.ts similarity index 93% rename from x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.ts rename to x-pack/plugins/lens/common/suffix_formatter/index.ts index f21b854128958d..12a4e02a81ef20 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.ts +++ b/x-pack/plugins/lens/common/suffix_formatter/index.ts @@ -10,9 +10,9 @@ import { FieldFormat, FieldFormatInstanceType, KBN_FIELD_TYPES, -} from '../../../../../src/plugins/data/public'; -import { FormatFactory } from '../types'; -import { TimeScaleUnit } from './time_scale'; +} from '../../../../../src/plugins/data/common'; +import type { FormatFactory } from '../types'; +import type { TimeScaleUnit } from '../expressions/time_scale'; const unitSuffixes: Record = { s: i18n.translate('xpack.lens.fieldFormats.suffix.s', { defaultMessage: '/s' }), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.test.ts b/x-pack/plugins/lens/common/suffix_formatter/suffix_formatter.test.ts similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.test.ts rename to x-pack/plugins/lens/common/suffix_formatter/suffix_formatter.test.ts index 4349b95c4deafa..c4379bdd1fb34c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/suffix_formatter.test.ts +++ b/x-pack/plugins/lens/common/suffix_formatter/suffix_formatter.test.ts @@ -6,7 +6,7 @@ */ import { FormatFactory } from '../types'; -import { getSuffixFormatter } from './suffix_formatter'; +import { getSuffixFormatter } from './index'; describe('suffix formatter', () => { it('should call nested formatter and apply suffix', () => { diff --git a/x-pack/plugins/lens/common/types.ts b/x-pack/plugins/lens/common/types.ts index 2ca31c08a4ec77..a60061a3aa054b 100644 --- a/x-pack/plugins/lens/common/types.ts +++ b/x-pack/plugins/lens/common/types.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { FilterMeta, Filter } from 'src/plugins/data/common'; +import type { FilterMeta, Filter, IFieldFormat } from '../../../../src/plugins/data/common'; +import type { Datatable, SerializedFieldFormat } from '../../../../src/plugins/expressions/common'; + +export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat; export interface ExistingFields { indexPatternTitle: string; @@ -24,3 +27,32 @@ export interface PersistableFilterMeta extends FilterMeta { export interface PersistableFilter extends Filter { meta: PersistableFilterMeta; } + +export interface LensMultiTable { + type: 'lens_multitable'; + tables: Record; + dateRange?: { + fromDate: Date; + toDate: Date; + }; +} + +export interface ColorStop { + color: string; + stop: number; +} + +export interface CustomPaletteParams { + name?: string; + reverse?: boolean; + rangeType?: 'number' | 'percent'; + continuity?: 'above' | 'below' | 'all' | 'none'; + progression?: 'fixed'; + rangeMin?: number; + rangeMax?: number; + stops?: ColorStop[]; + colorStops?: ColorStop[]; + steps?: number; +} + +export type RequiredPaletteParamTypes = Required; diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.test.tsx index aa8c6ffb26d170..fb9cb992fcf47d 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.test.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.test.tsx @@ -14,7 +14,7 @@ import { Datatable } from 'src/plugins/expressions/public'; import { IUiSettingsClient } from 'kibana/public'; import { act } from 'react-dom/test-utils'; import { ReactWrapper } from 'enzyme'; -import { Args, ColumnConfigArg } from '../expression'; +import { DatatableArgs, ColumnConfigArg } from '../../../common/expressions'; import { DataContextType } from './types'; import { chartPluginMock } from 'src/plugins/charts/public/mocks'; @@ -91,7 +91,7 @@ describe('datatable cell renderer', () => { const paletteRegistry = chartPluginMock.createPaletteRegistry(); const customPalette = paletteRegistry.get('custom'); - function getCellRenderer(columnConfig: Args) { + function getCellRenderer(columnConfig: DatatableArgs) { return createGridCell( { a: { convert: (x) => `formatted ${x}` } as FieldFormat, @@ -101,7 +101,7 @@ describe('datatable cell renderer', () => { ({ get: jest.fn() } as unknown) as IUiSettingsClient ); } - function getColumnConfiguration(): Args { + function getColumnConfiguration(): DatatableArgs { return { title: 'myData', columns: [ @@ -136,7 +136,10 @@ describe('datatable cell renderer', () => { }); } - async function renderCellComponent(columnConfig: Args, context: Partial = {}) { + async function renderCellComponent( + columnConfig: DatatableArgs, + context: Partial = {} + ) { const CellRendererWithPalette = getCellRenderer(columnConfig); const setCellProps = jest.fn(); diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.tsx index 5a3aa3b45b848c..6d6b2e4b1013fa 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/cell_value.tsx @@ -8,11 +8,11 @@ import React, { useContext, useEffect } from 'react'; import { EuiDataGridCellValueElementProps } from '@elastic/eui'; import { IUiSettingsClient } from 'kibana/public'; -import type { FormatFactory } from '../../types'; +import type { FormatFactory } from '../../../common'; +import { getOriginalId } from '../../../common/expressions'; +import type { ColumnConfig } from '../../../common/expressions'; import type { DataContextType } from './types'; -import { ColumnConfig } from './table_basic'; import { getContrastColor, getNumericValue } from '../../shared_components/coloring/utils'; -import { getOriginalId } from '../transpose_helpers'; export const createGridCell = ( formatters: Record>, diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/columns.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/columns.tsx index 4372e2cd9e9640..0bc249c783239e 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/columns.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/columns.tsx @@ -13,8 +13,8 @@ import { EuiListGroupItemProps, } from '@elastic/eui'; import type { Datatable, DatatableColumn, DatatableColumnMeta } from 'src/plugins/expressions'; -import type { FormatFactory } from '../../types'; -import { ColumnConfig } from './table_basic'; +import type { FormatFactory } from '../../../common'; +import type { ColumnConfig } from '../../../common/expressions'; export const createGridColumns = ( bucketColumns: string[], diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/dimension_editor.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/dimension_editor.tsx index 705484edcf0e6d..6840f4f13450c7 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/dimension_editor.tsx @@ -21,8 +21,7 @@ import { } from '@elastic/eui'; import { PaletteRegistry } from 'src/plugins/charts/public'; import { VisualizationDimensionEditorProps } from '../../types'; -import { ColumnState, DatatableVisualizationState } from '../visualization'; -import { getOriginalId } from '../transpose_helpers'; +import { DatatableVisualizationState } from '../visualization'; import { CustomizablePalette, applyPaletteParams, @@ -33,13 +32,16 @@ import { PalettePanelContainer, findMinMaxByColumnId, } from '../../shared_components/'; -import './dimension_editor.scss'; +import type { ColumnState } from '../../../common/expressions'; import { + isNumericFieldForDatatable, getDefaultSummaryLabel, getFinalSummaryConfiguration, getSummaryRowOptions, -} from '../summary'; -import { isNumericField } from '../utils'; + getOriginalId, +} from '../../../common/expressions'; + +import './dimension_editor.scss'; const idPrefix = htmlIdGenerator()(); @@ -93,7 +95,7 @@ export function TableDimensionEditor( const currentData = frame.activeData?.[state.layerId]; // either read config state or use same logic as chart itself - const isNumeric = isNumericField(currentData, accessor); + const isNumeric = isNumericFieldForDatatable(currentData, accessor); const currentAlignment = column?.alignment || (isNumeric ? 'right' : 'left'); const currentColorMode = column?.colorMode || 'none'; const hasDynamicColoring = currentColorMode !== 'none'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.test.ts b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.test.ts index 8490d33f83444d..bcce2fa2f6f693 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.test.ts +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.test.ts @@ -17,9 +17,8 @@ import { createGridHideHandler, createTransposeColumnFilterHandler, } from './table_actions'; -import { LensGridDirection } from './types'; -import { ColumnConfig } from './table_basic'; -import { LensMultiTable } from '../../types'; +import { LensMultiTable } from '../../../common'; +import { LensGridDirection, ColumnConfig } from '../../../common/expressions'; function getDefaultConfig(): ColumnConfig { return { diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts index 8615ed65363160..62c2ec3a7f7fde 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts @@ -7,15 +7,11 @@ import type { EuiDataGridSorting } from '@elastic/eui'; import type { Datatable, DatatableColumn } from 'src/plugins/expressions'; -import type { LensFilterEvent, LensMultiTable } from '../../types'; -import type { - LensGridDirection, - LensResizeAction, - LensSortAction, - LensToggleAction, -} from './types'; -import { ColumnConfig } from './table_basic'; -import { getOriginalId } from '../transpose_helpers'; +import type { LensFilterEvent } from '../../types'; +import type { LensMultiTable } from '../../../common'; +import type { LensResizeAction, LensSortAction, LensToggleAction } from './types'; +import type { ColumnConfig, LensGridDirection } from '../../../common/expressions'; +import { getOriginalId } from '../../../common/expressions'; export const createGridResizeHandler = ( columnConfig: ColumnConfig, diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx index ae51f7d42312f8..bb678a361e1741 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx @@ -15,8 +15,8 @@ import { VisualizationContainer } from '../../visualization_container'; import { EmptyPlaceholder } from '../../shared_components'; import { LensIconChartDatatable } from '../../assets/chart_datatable'; import { DataContext, DatatableComponent } from './table_basic'; -import { LensMultiTable } from '../../types'; -import { DatatableProps } from '../expression'; +import { LensMultiTable } from '../../../common'; +import { DatatableProps } from '../../../common/expressions'; import { chartPluginMock } from 'src/plugins/charts/public/mocks'; import { IUiSettingsClient } from 'kibana/public'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.tsx index 8ef64e4acdccc7..ac1324385dbd1f 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.tsx @@ -18,18 +18,17 @@ import { EuiDataGridSorting, EuiDataGridStyle, } from '@elastic/eui'; -import { CustomPaletteState, PaletteOutput } from 'src/plugins/charts/common'; -import { FormatFactory, LensFilterEvent, LensTableRowContextMenuEvent } from '../../types'; +import type { LensFilterEvent, LensTableRowContextMenuEvent } from '../../types'; +import type { FormatFactory } from '../../../common'; +import { LensGridDirection } from '../../../common/expressions'; import { VisualizationContainer } from '../../visualization_container'; import { EmptyPlaceholder, findMinMaxByColumnId } from '../../shared_components'; import { LensIconChartDatatable } from '../../assets/chart_datatable'; -import { ColumnState } from '../visualization'; -import { +import type { DataContextType, DatatableRenderProps, LensSortAction, LensResizeAction, - LensGridDirection, LensToggleAction, } from './types'; import { createGridColumns } from './columns'; @@ -42,8 +41,7 @@ import { createTransposeColumnFilterHandler, } from './table_actions'; import { CUSTOM_PALETTE } from '../../shared_components/coloring/constants'; -import { getFinalSummaryConfiguration } from '../summary'; -import { getOriginalId } from '../transpose_helpers'; +import { getOriginalId, getFinalSummaryConfiguration } from '../../../common/expressions'; export const DataContext = React.createContext({}); @@ -52,17 +50,6 @@ const gridStyle: EuiDataGridStyle = { header: 'underline', }; -export interface ColumnConfig { - columns: Array< - Omit & { - type: 'lens_datatable_column'; - palette?: PaletteOutput; - } - >; - sortingColumnId: string | undefined; - sortingDirection: LensGridDirection; -} - export const DatatableComponent = (props: DatatableRenderProps) => { const [firstTable] = Object.values(props.data.tables); diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/types.ts b/x-pack/plugins/lens/public/datatable_visualization/components/types.ts index 2095715756a532..f3d81c2d133400 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/types.ts +++ b/x-pack/plugins/lens/public/datatable_visualization/components/types.ts @@ -5,16 +5,14 @@ * 2.0. */ -import type { Direction } from '@elastic/eui'; import { IUiSettingsClient } from 'kibana/public'; import { CustomPaletteState, PaletteRegistry } from 'src/plugins/charts/public'; import type { IAggType } from 'src/plugins/data/public'; import type { Datatable, RenderMode } from 'src/plugins/expressions'; -import type { FormatFactory, ILensInterpreterRenderHandlers, LensEditEvent } from '../../types'; -import type { DatatableProps } from '../expression'; +import type { ILensInterpreterRenderHandlers, LensEditEvent } from '../../types'; import { LENS_EDIT_SORT_ACTION, LENS_EDIT_RESIZE_ACTION, LENS_TOGGLE_ACTION } from './constants'; - -export type LensGridDirection = 'none' | Direction; +import type { FormatFactory } from '../../../common'; +import type { DatatableProps, LensGridDirection } from '../../../common/expressions'; export interface LensSortActionData { columnId: string | undefined; @@ -49,12 +47,6 @@ export type DatatableRenderProps = DatatableProps & { rowHasRowClickTriggerActions?: boolean[]; }; -export interface DatatableRender { - type: 'render'; - as: 'lens_datatable_renderer'; - value: DatatableProps; -} - export interface DataContextType { table?: Datatable; rowHasRowClickTriggerActions?: boolean[]; diff --git a/x-pack/plugins/lens/public/datatable_visualization/expression.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/expression.test.tsx index 3ba448b49afc9d..4b4d2275d0dec0 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/expression.test.tsx @@ -5,10 +5,11 @@ * 2.0. */ -import { DatatableProps, getDatatable } from './expression'; -import { LensMultiTable } from '../types'; +import { DatatableProps } from '../../common/expressions'; +import type { LensMultiTable } from '../../common'; import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; import { IFieldFormat } from '../../../../../src/plugins/data/public'; +import { getDatatable } from './expression'; function sampleArgs() { const indexPatternId = 'indexPatternId'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx index 79a541b0288ab6..4e541bce9a8c25 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx @@ -7,194 +7,20 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { cloneDeep } from 'lodash'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; import type { IAggType } from 'src/plugins/data/public'; -import { - DatatableColumnMeta, - ExpressionFunctionDefinition, - ExpressionRenderDefinition, -} from 'src/plugins/expressions'; -import { CustomPaletteState, PaletteOutput } from 'src/plugins/charts/common'; import { PaletteRegistry } from 'src/plugins/charts/public'; import { IUiSettingsClient } from 'kibana/public'; -import { getSortingCriteria } from './sorting'; - +import { ExpressionRenderDefinition } from 'src/plugins/expressions'; import { DatatableComponent } from './components/table_basic'; -import { ColumnState } from './visualization'; - -import type { FormatFactory, ILensInterpreterRenderHandlers, LensMultiTable } from '../types'; -import type { DatatableRender } from './components/types'; -import { transposeTable } from './transpose_helpers'; -import { computeSummaryRowForColumn } from './summary'; - -export type ColumnConfigArg = Omit & { - type: 'lens_datatable_column'; - palette?: PaletteOutput; - summaryRowValue?: unknown; -}; - -export interface Args { - title: string; - description?: string; - columns: ColumnConfigArg[]; - sortingColumnId: string | undefined; - sortingDirection: 'asc' | 'desc' | 'none'; -} - -export interface DatatableProps { - data: LensMultiTable; - untransposedData?: LensMultiTable; - args: Args; -} - -function isRange(meta: { params?: { id?: string } } | undefined) { - return meta?.params?.id === 'range'; -} - -export const getDatatable = ({ - formatFactory, -}: { - formatFactory: FormatFactory; -}): ExpressionFunctionDefinition<'lens_datatable', LensMultiTable, Args, DatatableRender> => ({ - name: 'lens_datatable', - type: 'render', - inputTypes: ['lens_multitable'], - help: i18n.translate('xpack.lens.datatable.expressionHelpLabel', { - defaultMessage: 'Datatable renderer', - }), - args: { - title: { - types: ['string'], - help: i18n.translate('xpack.lens.datatable.titleLabel', { - defaultMessage: 'Title', - }), - }, - description: { - types: ['string'], - help: '', - }, - columns: { - types: ['lens_datatable_column'], - help: '', - multi: true, - }, - sortingColumnId: { - types: ['string'], - help: '', - }, - sortingDirection: { - types: ['string'], - help: '', - }, - }, - fn(data, args, context) { - let untransposedData: LensMultiTable | undefined; - // do the sorting at this level to propagate it also at CSV download - const [firstTable] = Object.values(data.tables); - const [layerId] = Object.keys(context.inspectorAdapters.tables || {}); - const formatters: Record> = {}; - - firstTable.columns.forEach((column) => { - formatters[column.id] = formatFactory(column.meta?.params); - }); - - const hasTransposedColumns = args.columns.some((c) => c.isTransposed); - if (hasTransposedColumns) { - // store original shape of data separately - untransposedData = cloneDeep(data); - // transposes table and args inplace - transposeTable(args, firstTable, formatters); - } - - const { sortingColumnId: sortBy, sortingDirection: sortDirection } = args; - - const columnsReverseLookup = firstTable.columns.reduce< - Record - >((memo, { id, name, meta }, i) => { - memo[id] = { name, index: i, meta }; - return memo; - }, {}); - - const columnsWithSummary = args.columns.filter((c) => c.summaryRow); - for (const column of columnsWithSummary) { - column.summaryRowValue = computeSummaryRowForColumn( - column, - firstTable, - formatters, - formatFactory({ id: 'number' }) - ); - } - - if (sortBy && columnsReverseLookup[sortBy] && sortDirection !== 'none') { - // Sort on raw values for these types, while use the formatted value for the rest - const sortingCriteria = getSortingCriteria( - isRange(columnsReverseLookup[sortBy]?.meta) - ? 'range' - : columnsReverseLookup[sortBy]?.meta?.type, - sortBy, - formatters[sortBy], - sortDirection - ); - // replace the table here - context.inspectorAdapters.tables[layerId].rows = (firstTable.rows || []) - .slice() - .sort(sortingCriteria); - // replace also the local copy - firstTable.rows = context.inspectorAdapters.tables[layerId].rows; - } else { - args.sortingColumnId = undefined; - args.sortingDirection = 'none'; - } - return { - type: 'render', - as: 'lens_datatable_renderer', - value: { - data, - untransposedData, - args, - }, - }; - }, -}); -type DatatableColumnResult = ColumnState & { type: 'lens_datatable_column' }; +import type { ILensInterpreterRenderHandlers } from '../types'; +import type { FormatFactory } from '../../common'; +import { DatatableProps } from '../../common/expressions'; -export const datatableColumn: ExpressionFunctionDefinition< - 'lens_datatable_column', - null, - ColumnState, - DatatableColumnResult -> = { - name: 'lens_datatable_column', - aliases: [], - type: 'lens_datatable_column', - help: '', - inputTypes: ['null'], - args: { - columnId: { types: ['string'], help: '' }, - alignment: { types: ['string'], help: '' }, - hidden: { types: ['boolean'], help: '' }, - width: { types: ['number'], help: '' }, - isTransposed: { types: ['boolean'], help: '' }, - transposable: { types: ['boolean'], help: '' }, - colorMode: { types: ['string'], help: '' }, - palette: { - types: ['palette'], - help: '', - }, - summaryRow: { types: ['string'], help: '' }, - summaryLabel: { types: ['string'], help: '' }, - }, - fn: function fn(input: unknown, args: ColumnState) { - return { - type: 'lens_datatable_column', - ...args, - }; - }, -}; +export { datatableColumn, getDatatable } from '../../common/expressions'; export const getDatatableRenderer = (dependencies: { formatFactory: FormatFactory; diff --git a/x-pack/plugins/lens/public/datatable_visualization/index.ts b/x-pack/plugins/lens/public/datatable_visualization/index.ts index 7f48d00d00f7f7..b4f37faf0bc005 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/index.ts +++ b/x-pack/plugins/lens/public/datatable_visualization/index.ts @@ -5,11 +5,12 @@ * 2.0. */ -import { CoreSetup } from 'kibana/public'; -import { ChartsPluginSetup } from 'src/plugins/charts/public'; -import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; -import { EditorFrameSetup, FormatFactory } from '../types'; -import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; +import type { CoreSetup } from 'kibana/public'; +import type { ChartsPluginSetup } from 'src/plugins/charts/public'; +import type { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; +import type { EditorFrameSetup } from '../types'; +import type { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; +import type { FormatFactory } from '../../common'; interface DatatableVisualizationPluginStartPlugins { data: DataPublicPluginStart; diff --git a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx index e7ab4aab88f2e8..691fce0ed70d28 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx @@ -10,9 +10,8 @@ import { render } from 'react-dom'; import { Ast } from '@kbn/interpreter/common'; import { I18nProvider } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { DatatableColumn } from 'src/plugins/expressions/public'; -import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; -import { +import type { PaletteRegistry } from 'src/plugins/charts/public'; +import type { SuggestionRequest, Visualization, VisualizationSuggestion, @@ -21,32 +20,9 @@ import { import { LensIconChartDatatable } from '../assets/chart_datatable'; import { TableDimensionEditor } from './components/dimension_editor'; import { CUSTOM_PALETTE } from '../shared_components/coloring/constants'; -import { CustomPaletteParams } from '../shared_components/coloring/types'; import { getStopsForFixedMode } from '../shared_components'; -import { getDefaultSummaryLabel } from './summary'; - -export interface ColumnState { - columnId: string; - width?: number; - hidden?: boolean; - isTransposed?: boolean; - // These flags are necessary to transpose columns and map them back later - // They are set automatically and are not user-editable - transposable?: boolean; - originalColumnId?: string; - originalName?: string; - bucketValues?: Array<{ originalBucketColumn: DatatableColumn; value: unknown }>; - alignment?: 'left' | 'right' | 'center'; - palette?: PaletteOutput; - colorMode?: 'none' | 'cell' | 'text'; - summaryRow?: 'none' | 'sum' | 'avg' | 'count' | 'min' | 'max'; - summaryLabel?: string; -} - -export interface SortingState { - columnId: string | undefined; - direction: 'asc' | 'desc' | 'none'; -} +import { getDefaultSummaryLabel } from '../../common/expressions'; +import type { ColumnState, SortingState } from '../../common/expressions'; export interface DatatableVisualizationState { columns: ColumnState[]; diff --git a/x-pack/plugins/lens/public/editor_frame_service/service.tsx b/x-pack/plugins/lens/public/editor_frame_service/service.tsx index 63340795ec6c8d..b3574f19b5caf9 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx @@ -22,7 +22,7 @@ import { EditorFrameStart, } from '../types'; import { Document } from '../persistence/saved_object_store'; -import { mergeTables } from './merge_tables'; +import { mergeTables } from '../../common/expressions'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; import { DashboardStart } from '../../../../../src/plugins/dashboard/public'; diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx index e27abc4ae32eca..e8095f6c741a4d 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx @@ -23,9 +23,8 @@ import type { LensByReferenceInput, LensByValueInput } from './embeddable'; import type { Document } from '../persistence'; import type { IndexPatternPersistedState } from '../indexpattern_datasource/types'; import type { XYState } from '../xy_visualization/types'; -import type { PieVisualizationState } from '../pie_visualization/types'; +import type { PieVisualizationState, MetricState } from '../../common/expressions'; import type { DatatableVisualizationState } from '../datatable_visualization/visualization'; -import type { MetricState } from '../metric_visualization/types'; type LensAttributes = Omit< Document, diff --git a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx index 3e8e9d184ed8ac..15e9963ff57406 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx @@ -16,11 +16,11 @@ import { ScaleType, Settings, } from '@elastic/charts'; -import { CustomPaletteState } from 'src/plugins/charts/public'; +import type { CustomPaletteState } from 'src/plugins/charts/public'; import { VisualizationContainer } from '../visualization_container'; -import { HeatmapRenderProps } from './types'; +import type { HeatmapRenderProps } from './types'; import './index.scss'; -import { LensBrushEvent, LensFilterEvent } from '../types'; +import type { LensBrushEvent, LensFilterEvent } from '../types'; import { applyPaletteParams, defaultPaletteParams, diff --git a/x-pack/plugins/lens/public/heatmap_visualization/dimension_editor.tsx b/x-pack/plugins/lens/public/heatmap_visualization/dimension_editor.tsx index 85daa4805b9ece..ca4a65e6fb10f4 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/dimension_editor.tsx @@ -14,8 +14,8 @@ import { EuiFlexGroup, EuiButtonEmpty, } from '@elastic/eui'; -import { PaletteRegistry } from 'src/plugins/charts/public'; -import { VisualizationDimensionEditorProps } from '../types'; +import type { PaletteRegistry } from 'src/plugins/charts/public'; +import type { VisualizationDimensionEditorProps } from '../types'; import { CustomizablePalette, FIXED_PROGRESSION, @@ -23,7 +23,7 @@ import { PalettePanelContainer, } from '../shared_components/'; import './dimension_editor.scss'; -import { HeatmapVisualizationState } from './types'; +import type { HeatmapVisualizationState } from './types'; import { getSafePaletteParams } from './utils'; export function HeatmapDimensionEditor( diff --git a/x-pack/plugins/lens/public/heatmap_visualization/expression.tsx b/x-pack/plugins/lens/public/heatmap_visualization/expression.tsx index 37dad117bb7830..27be4b9ce7fe97 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/expression.tsx @@ -9,221 +9,15 @@ import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; import ReactDOM from 'react-dom'; import React from 'react'; -import { Position } from '@elastic/charts'; -import { - ExpressionFunctionDefinition, - IInterpreterRenderHandlers, -} from '../../../../../src/plugins/expressions'; -import { FormatFactory, LensBrushEvent, LensFilterEvent, LensMultiTable } from '../types'; -import { - FUNCTION_NAME, - HEATMAP_GRID_FUNCTION, - LEGEND_FUNCTION, - LENS_HEATMAP_RENDERER, -} from './constants'; -import type { - HeatmapExpressionArgs, - HeatmapExpressionProps, - HeatmapGridConfig, - HeatmapGridConfigResult, - HeatmapRender, - LegendConfigResult, -} from './types'; -import { HeatmapLegendConfig } from './types'; -import { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; +import type { IInterpreterRenderHandlers } from '../../../../../src/plugins/expressions'; +import type { LensBrushEvent, LensFilterEvent } from '../types'; +import type { FormatFactory } from '../../common'; +import { LENS_HEATMAP_RENDERER } from './constants'; +import type { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; import { HeatmapChartReportable } from './chart_component'; +import type { HeatmapExpressionProps } from './types'; -export const heatmapGridConfig: ExpressionFunctionDefinition< - typeof HEATMAP_GRID_FUNCTION, - null, - HeatmapGridConfig, - HeatmapGridConfigResult -> = { - name: HEATMAP_GRID_FUNCTION, - aliases: [], - type: HEATMAP_GRID_FUNCTION, - help: `Configure the heatmap layout `, - inputTypes: ['null'], - args: { - // grid - strokeWidth: { - types: ['number'], - help: i18n.translate('xpack.lens.heatmapChart.config.strokeWidth.help', { - defaultMessage: 'Specifies the grid stroke width', - }), - required: false, - }, - strokeColor: { - types: ['string'], - help: i18n.translate('xpack.lens.heatmapChart.config.strokeColor.help', { - defaultMessage: 'Specifies the grid stroke color', - }), - required: false, - }, - cellHeight: { - types: ['number'], - help: i18n.translate('xpack.lens.heatmapChart.config.cellHeight.help', { - defaultMessage: 'Specifies the grid cell height', - }), - required: false, - }, - cellWidth: { - types: ['number'], - help: i18n.translate('xpack.lens.heatmapChart.config.cellWidth.help', { - defaultMessage: 'Specifies the grid cell width', - }), - required: false, - }, - // cells - isCellLabelVisible: { - types: ['boolean'], - help: i18n.translate('xpack.lens.heatmapChart.config.isCellLabelVisible.help', { - defaultMessage: 'Specifies whether or not the cell label is visible.', - }), - }, - // Y-axis - isYAxisLabelVisible: { - types: ['boolean'], - help: i18n.translate('xpack.lens.heatmapChart.config.isYAxisLabelVisible.help', { - defaultMessage: 'Specifies whether or not the Y-axis labels are visible.', - }), - }, - yAxisLabelWidth: { - types: ['number'], - help: i18n.translate('xpack.lens.heatmapChart.config.yAxisLabelWidth.help', { - defaultMessage: 'Specifies the width of the Y-axis labels.', - }), - required: false, - }, - yAxisLabelColor: { - types: ['string'], - help: i18n.translate('xpack.lens.heatmapChart.config.yAxisLabelColor.help', { - defaultMessage: 'Specifies the color of the Y-axis labels.', - }), - required: false, - }, - // X-axis - isXAxisLabelVisible: { - types: ['boolean'], - help: i18n.translate('xpack.lens.heatmapChart.config.isXAxisLabelVisible.help', { - defaultMessage: 'Specifies whether or not the X-axis labels are visible.', - }), - }, - }, - fn(input, args) { - return { - type: HEATMAP_GRID_FUNCTION, - ...args, - }; - }, -}; - -/** - * TODO check if it's possible to make a shared function - * based on the XY chart - */ -export const heatmapLegendConfig: ExpressionFunctionDefinition< - typeof LEGEND_FUNCTION, - null, - HeatmapLegendConfig, - LegendConfigResult -> = { - name: LEGEND_FUNCTION, - aliases: [], - type: LEGEND_FUNCTION, - help: `Configure the heatmap chart's legend`, - inputTypes: ['null'], - args: { - isVisible: { - types: ['boolean'], - help: i18n.translate('xpack.lens.heatmapChart.legend.isVisible.help', { - defaultMessage: 'Specifies whether or not the legend is visible.', - }), - }, - position: { - types: ['string'], - options: [Position.Top, Position.Right, Position.Bottom, Position.Left], - help: i18n.translate('xpack.lens.heatmapChart.legend.position.help', { - defaultMessage: 'Specifies the legend position.', - }), - }, - }, - fn(input, args) { - return { - type: LEGEND_FUNCTION, - ...args, - }; - }, -}; - -export const heatmap: ExpressionFunctionDefinition< - typeof FUNCTION_NAME, - LensMultiTable, - HeatmapExpressionArgs, - HeatmapRender -> = { - name: FUNCTION_NAME, - type: 'render', - help: i18n.translate('xpack.lens.heatmap.expressionHelpLabel', { - defaultMessage: 'Heatmap renderer', - }), - args: { - title: { - types: ['string'], - help: i18n.translate('xpack.lens.heatmap.titleLabel', { - defaultMessage: 'Title', - }), - }, - description: { - types: ['string'], - help: '', - }, - xAccessor: { - types: ['string'], - help: '', - }, - yAccessor: { - types: ['string'], - help: '', - }, - valueAccessor: { - types: ['string'], - help: '', - }, - shape: { - types: ['string'], - help: '', - }, - palette: { - default: `{theme "palette" default={system_palette name="default"} }`, - help: '', - types: ['palette'], - }, - legend: { - types: [LEGEND_FUNCTION], - help: i18n.translate('xpack.lens.heatmapChart.legend.help', { - defaultMessage: 'Configure the chart legend.', - }), - }, - gridConfig: { - types: [HEATMAP_GRID_FUNCTION], - help: i18n.translate('xpack.lens.heatmapChart.gridConfig.help', { - defaultMessage: 'Configure the heatmap layout.', - }), - }, - }, - inputTypes: ['lens_multitable'], - fn(data: LensMultiTable, args: HeatmapExpressionArgs) { - return { - type: 'render', - as: LENS_HEATMAP_RENDERER, - value: { - data, - args, - }, - }; - }, -}; +export { heatmapGridConfig, heatmapLegendConfig, heatmap } from '../../common/expressions'; export const getHeatmapRenderer = (dependencies: { formatFactory: Promise; diff --git a/x-pack/plugins/lens/public/heatmap_visualization/index.ts b/x-pack/plugins/lens/public/heatmap_visualization/index.ts index 4599bd8d2a2087..11f9b907eb9291 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/index.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/index.ts @@ -5,11 +5,12 @@ * 2.0. */ -import { CoreSetup } from 'kibana/public'; -import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; -import { EditorFrameSetup, FormatFactory } from '../types'; -import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; +import type { CoreSetup } from 'kibana/public'; +import type { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; +import type { EditorFrameSetup } from '../types'; +import type { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; import { getTimeZone } from '../utils'; +import type { FormatFactory } from '../../common'; export interface HeatmapVisualizationPluginSetupPlugins { expressions: ExpressionsSetup; diff --git a/x-pack/plugins/lens/public/heatmap_visualization/suggestions.test.ts b/x-pack/plugins/lens/public/heatmap_visualization/suggestions.test.ts index c11078be6c8b9c..d7443ea8fe43df 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/suggestions.test.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/suggestions.test.ts @@ -5,10 +5,10 @@ * 2.0. */ +import { Position } from '@elastic/charts'; import { getSuggestions } from './suggestions'; -import { HeatmapVisualizationState } from './types'; +import type { HeatmapVisualizationState } from './types'; import { HEATMAP_GRID_FUNCTION, LEGEND_FUNCTION } from './constants'; -import { Position } from '@elastic/charts'; describe('heatmap suggestions', () => { describe('rejects suggestions', () => { diff --git a/x-pack/plugins/lens/public/heatmap_visualization/suggestions.ts b/x-pack/plugins/lens/public/heatmap_visualization/suggestions.ts index 5cddebe2cc2308..3f27d5e81b5070 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/suggestions.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/suggestions.ts @@ -8,8 +8,8 @@ import { partition } from 'lodash'; import { Position } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; -import { Visualization } from '../types'; -import { HeatmapVisualizationState } from './types'; +import type { Visualization } from '../types'; +import type { HeatmapVisualizationState } from './types'; import { CHART_SHAPES, HEATMAP_GRID_FUNCTION, LEGEND_FUNCTION } from './constants'; export const getSuggestions: Visualization['getSuggestions'] = ({ diff --git a/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx b/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx index 6fd863ba919368..c35143773551d2 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx @@ -9,9 +9,9 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Position } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; -import { VisualizationToolbarProps } from '../types'; +import type { VisualizationToolbarProps } from '../types'; import { LegendSettingsPopover } from '../shared_components'; -import { HeatmapVisualizationState } from './types'; +import type { HeatmapVisualizationState } from './types'; const legendOptions: Array<{ id: string; value: 'auto' | 'show' | 'hide'; label: string }> = [ { diff --git a/x-pack/plugins/lens/public/heatmap_visualization/types.ts b/x-pack/plugins/lens/public/heatmap_visualization/types.ts index 32e3079c951d4a..0cf830bea609ac 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/types.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/types.ts @@ -5,17 +5,12 @@ * 2.0. */ -import { Position } from '@elastic/charts'; -import { PaletteOutput } from '../../../../../src/plugins/charts/common'; -import { FormatFactory, LensBrushEvent, LensFilterEvent, LensMultiTable } from '../types'; -import { - CHART_SHAPES, - HEATMAP_GRID_FUNCTION, - LEGEND_FUNCTION, - LENS_HEATMAP_RENDERER, -} from './constants'; -import { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; -import { CustomPaletteParams } from '../shared_components'; +import type { PaletteOutput } from '../../../../../src/plugins/charts/common'; +import type { LensBrushEvent, LensFilterEvent } from '../types'; +import type { LensMultiTable, FormatFactory, CustomPaletteParams } from '../../common'; +import type { HeatmapGridConfigResult, HeatmapLegendConfigResult } from '../../common/expressions'; +import { CHART_SHAPES, LENS_HEATMAP_RENDERER } from './constants'; +import type { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; export type ChartShapes = typeof CHART_SHAPES[keyof typeof CHART_SHAPES]; @@ -24,7 +19,7 @@ export interface SharedHeatmapLayerState { xAccessor?: string; yAccessor?: string; valueAccessor?: string; - legend: LegendConfigResult; + legend: HeatmapLegendConfigResult; gridConfig: HeatmapGridConfigResult; } @@ -62,34 +57,3 @@ export type HeatmapRenderProps = HeatmapExpressionProps & { onSelectRange: (data: LensBrushEvent['data']) => void; paletteService: PaletteRegistry; }; - -export interface HeatmapLegendConfig { - /** - * Flag whether the legend should be shown. If there is just a single series, it will be hidden - */ - isVisible: boolean; - /** - * Position of the legend relative to the chart - */ - position: Position; -} - -export type LegendConfigResult = HeatmapLegendConfig & { type: typeof LEGEND_FUNCTION }; - -export interface HeatmapGridConfig { - // grid - strokeWidth?: number; - strokeColor?: string; - cellHeight?: number; - cellWidth?: number; - // cells - isCellLabelVisible: boolean; - // Y-axis - isYAxisLabelVisible: boolean; - yAxisLabelWidth?: number; - yAxisLabelColor?: string; - // X-axis - isXAxisLabelVisible: boolean; -} - -export type HeatmapGridConfigResult = HeatmapGridConfig & { type: typeof HEATMAP_GRID_FUNCTION }; diff --git a/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts b/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts index 316a3ef36d66cb..6cbe27fbf323fd 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts @@ -19,8 +19,8 @@ import { LEGEND_FUNCTION, } from './constants'; import { Position } from '@elastic/charts'; -import { HeatmapVisualizationState } from './types'; -import { DatasourcePublicAPI, Operation } from '../types'; +import type { HeatmapVisualizationState } from './types'; +import type { DatasourcePublicAPI, Operation } from '../types'; import { chartPluginMock } from 'src/plugins/charts/public/mocks'; function exampleState(): HeatmapVisualizationState { diff --git a/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx b/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx index 12fe28f801ef2c..716792805e1b56 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx @@ -12,8 +12,8 @@ import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { Ast } from '@kbn/interpreter/common'; import { Position } from '@elastic/charts'; import { PaletteRegistry } from '../../../../../src/plugins/charts/public'; -import { OperationMetadata, Visualization } from '../types'; -import { HeatmapVisualizationState } from './types'; +import type { OperationMetadata, Visualization } from '../types'; +import type { HeatmapVisualizationState } from './types'; import { getSuggestions } from './suggestions'; import { CHART_NAMES, @@ -27,9 +27,10 @@ import { } from './constants'; import { HeatmapToolbar } from './toolbar_component'; import { LensIconChartHeatmap } from '../assets/chart_heatmap'; -import { CustomPaletteParams, CUSTOM_PALETTE, getStopsForFixedMode } from '../shared_components'; +import { CUSTOM_PALETTE, getStopsForFixedMode } from '../shared_components'; import { HeatmapDimensionEditor } from './dimension_editor'; import { getSafePaletteParams } from './utils'; +import type { CustomPaletteParams } from '../../common'; const groupLabelForBar = i18n.translate('xpack.lens.heatmapVisualization.heatmapGroupLabel', { defaultMessage: 'Heatmap', diff --git a/x-pack/plugins/lens/public/index.ts b/x-pack/plugins/lens/public/index.ts index 76afe7260a35a6..84302f25d0a023 100644 --- a/x-pack/plugins/lens/public/index.ts +++ b/x-pack/plugins/lens/public/index.ts @@ -11,8 +11,13 @@ export type { EmbeddableComponentProps, TypedLensByValueInput, } from './embeddable/embeddable_component'; +export type { XYState } from './xy_visualization/types'; +export type { DataType, OperationMetadata } from './types'; export type { - XYState, + PieVisualizationState, + PieLayerState, + SharedPieLayerState, + MetricState, AxesSettingsConfig, XYLayerConfig, LegendConfig, @@ -21,15 +26,8 @@ export type { YAxisMode, XYCurveType, YConfig, -} from './xy_visualization/types'; -export type { DataType, OperationMetadata } from './types'; -export type { - PieVisualizationState, - PieLayerState, - SharedPieLayerState, -} from './pie_visualization/types'; +} from '../common/expressions'; export type { DatatableVisualizationState } from './datatable_visualization/visualization'; -export type { MetricState } from './metric_visualization/types'; export type { IndexPatternPersistedState, PersistedIndexPatternLayer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx index 3965f992805b5d..d6091557ce235a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx @@ -16,7 +16,7 @@ import { IndexPatternColumn } from '../indexpattern'; import { isColumnInvalid } from '../utils'; import { IndexPatternPrivateState } from '../types'; import { DimensionEditor } from './dimension_editor'; -import { DateRange } from '../../../common'; +import type { DateRange } from '../../../common'; import { getOperationSupportMatrix } from './operation_support'; export type IndexPatternDimensionTriggerProps = DatasourceDimensionTriggerProps & { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx index 61e5da5931e88e..7c611230683d39 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx @@ -15,8 +15,8 @@ import { IndexPatternColumn, operationDefinitionMap, } from '../operations'; -import { unitSuffixesLong } from '../suffix_formatter'; -import { TimeScaleUnit } from '../time_scale'; +import type { TimeScaleUnit } from '../../../common/expressions'; +import { unitSuffixesLong } from '../../../common/suffix_formatter'; import { IndexPatternLayer } from '../types'; export function setTimeScaling( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index f8bc84643bcaba..35afd28c0f1ab7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts @@ -43,14 +43,14 @@ export class IndexPatternDatasource { renameColumns, formatColumn, counterRate, - getTimeScaleFunction, + timeScale, getSuffixFormatter, } = await import('../async_services'); return core .getStartServices() .then(([coreStart, { data, indexPatternFieldEditor, uiActions }]) => { data.fieldFormats.register([getSuffixFormatter(data.fieldFormats.deserialize)]); - expressions.registerFunction(getTimeScaleFunction(data)); + expressions.registerFunction(timeScale); expressions.registerFunction(counterRate); expressions.registerFunction(renameColumns); expressions.registerFunction(formatColumn); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 34be770a7f50d6..2cbe801a5b7b85 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -69,11 +69,15 @@ export function columnToOperation(column: IndexPatternColumn, uniqueLabel?: stri }; } -export * from './rename_columns'; -export * from './format_column'; -export * from './time_scale'; -export * from './counter_rate'; -export * from './suffix_formatter'; +export { + CounterRateArgs, + ExpressionFunctionCounterRate, + counterRate, +} from '../../common/expressions'; +export { FormatColumnArgs, supportedFormats, formatColumn } from '../../common/expressions'; +export { getSuffixFormatter, unitSuffixesLong } from '../../common/suffix_formatter'; +export { timeScale, TimeScaleArgs } from '../../common/expressions'; +export { renameColumns } from '../../common/expressions'; export function getIndexPatternDatasource({ core, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts index 87116f71919b56..34b33d35d41399 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import type { ExpressionFunctionAST } from '@kbn/interpreter/common'; import memoizeOne from 'memoize-one'; -import type { TimeScaleUnit } from '../../../time_scale'; +import type { TimeScaleUnit } from '../../../../../common/expressions'; import type { IndexPattern, IndexPatternLayer } from '../../../types'; import { adjustTimeScaleLabelSuffix } from '../../time_scale_utils'; import type { ReferenceBasedIndexPatternColumn } from '../column_types'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts index ae606a5851665e..15bd7d4242b921 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts @@ -7,7 +7,7 @@ import { Query } from 'src/plugins/data/public'; import type { Operation } from '../../../types'; -import { TimeScaleUnit } from '../../time_scale'; +import type { TimeScaleUnit } from '../../../../common/expressions'; import type { OperationType } from '../definitions'; export interface BaseIndexPatternColumn extends Operation { 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 fd212580028087..cb737d694295dc 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 @@ -17,7 +17,7 @@ import { RangeEditor } from './range_editor'; import { OperationDefinition } from '../index'; import { FieldBasedIndexPatternColumn } from '../column_types'; import { updateColumnParam } from '../../layer_helpers'; -import { supportedFormats } from '../../../format_column'; +import { supportedFormats } from '../../../../../common/expressions'; import { MODES, AUTO_BARS, DEFAULT_INTERVAL, MIN_HISTOGRAM_BARS, SLICES } from './constants'; import { IndexPattern, IndexPatternField } from '../../../types'; import { getInvalidFieldMessage, isValidNumber } from '../helpers'; 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 b5b1960b7b7691..1e0d0792e132a6 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 @@ -32,7 +32,7 @@ import { getSortScoreByPriority } from './operations'; import { generateId } from '../../id_generator'; import { ReferenceBasedIndexPatternColumn } from './definitions/column_types'; import { FormulaIndexPatternColumn, regenerateLayerFromAst } from './definitions/formula'; -import { TimeScaleUnit } from '../time_scale'; +import type { TimeScaleUnit } from '../../../common/expressions'; interface ColumnAdvancedParams { filter?: Query | undefined; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts index 152fcaa457c3bc..dbdfd5c564125e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts @@ -6,7 +6,7 @@ */ import type { IndexPatternLayer } from '../types'; -import type { TimeScaleUnit } from '../time_scale'; +import type { TimeScaleUnit } from '../../../common/expressions'; import type { IndexPatternColumn } from './definitions'; import { adjustTimeScaleLabelSuffix, adjustTimeScaleOnOtherColumnChange } from './time_scale_utils'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts index a0b61060b9f3ad..a6c056933f022d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { unitSuffixesLong } from '../suffix_formatter'; -import type { TimeScaleUnit } from '../time_scale'; +import { unitSuffixesLong } from '../../../common/suffix_formatter'; +import type { TimeScaleUnit } from '../../../common/expressions'; import type { IndexPatternLayer } from '../types'; import type { IndexPatternColumn } from './definitions'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_scale.ts b/x-pack/plugins/lens/public/indexpattern_datasource/time_scale.ts deleted file mode 100644 index 368e06110efc98..00000000000000 --- a/x-pack/plugins/lens/public/indexpattern_datasource/time_scale.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import moment from 'moment-timezone'; -import { i18n } from '@kbn/i18n'; -import { ExpressionFunctionDefinition, Datatable } from 'src/plugins/expressions/public'; -import { DataPublicPluginStart } from 'src/plugins/data/public'; -import { search } from '../../../../../src/plugins/data/public'; -import { buildResultColumns } from '../../../../../src/plugins/expressions/common'; - -export type TimeScaleUnit = 's' | 'm' | 'h' | 'd'; - -export interface TimeScaleArgs { - dateColumnId: string; - inputColumnId: string; - outputColumnId: string; - targetUnit: TimeScaleUnit; - outputColumnName?: string; -} - -const unitInMs: Record = { - s: 1000, - m: 1000 * 60, - h: 1000 * 60 * 60, - d: 1000 * 60 * 60 * 24, -}; - -export function getTimeScaleFunction(data: DataPublicPluginStart) { - const timeScale: ExpressionFunctionDefinition< - 'lens_time_scale', - Datatable, - TimeScaleArgs, - Promise - > = { - name: 'lens_time_scale', - type: 'datatable', - help: '', - args: { - dateColumnId: { - types: ['string'], - help: '', - required: true, - }, - inputColumnId: { - types: ['string'], - help: '', - required: true, - }, - outputColumnId: { - types: ['string'], - help: '', - required: true, - }, - outputColumnName: { - types: ['string'], - help: '', - }, - targetUnit: { - types: ['string'], - options: ['s', 'm', 'h', 'd'], - help: '', - required: true, - }, - }, - inputTypes: ['datatable'], - async fn( - input, - { dateColumnId, inputColumnId, outputColumnId, outputColumnName, targetUnit }: TimeScaleArgs - ) { - const dateColumnDefinition = input.columns.find((column) => column.id === dateColumnId); - - if (!dateColumnDefinition) { - throw new Error( - i18n.translate('xpack.lens.functions.timeScale.dateColumnMissingMessage', { - defaultMessage: 'Specified dateColumnId {columnId} does not exist.', - values: { - columnId: dateColumnId, - }, - }) - ); - } - - const resultColumns = buildResultColumns( - input, - outputColumnId, - inputColumnId, - outputColumnName, - { allowColumnOverwrite: true } - ); - - if (!resultColumns) { - return input; - } - - const targetUnitInMs = unitInMs[targetUnit]; - const timeInfo = search.aggs.getDateHistogramMetaDataByDatatableColumn(dateColumnDefinition); - const intervalDuration = timeInfo?.interval && search.aggs.parseInterval(timeInfo.interval); - - if (!timeInfo || !intervalDuration) { - throw new Error( - i18n.translate('xpack.lens.functions.timeScale.timeInfoMissingMessage', { - defaultMessage: 'Could not fetch date histogram information', - }) - ); - } - // the datemath plugin always parses dates by using the current default moment time zone. - // to use the configured time zone, we are switching just for the bounds calculation. - const defaultTimezone = moment().zoneName(); - moment.tz.setDefault(timeInfo.timeZone); - - const timeBounds = - timeInfo.timeRange && data.query.timefilter.timefilter.calculateBounds(timeInfo.timeRange); - - const result = { - ...input, - columns: resultColumns, - rows: input.rows.map((row) => { - const newRow = { ...row }; - - let startOfBucket = moment(row[dateColumnId]); - let endOfBucket = startOfBucket.clone().add(intervalDuration); - if (timeBounds && timeBounds.min) { - startOfBucket = moment.max(startOfBucket, timeBounds.min); - } - if (timeBounds && timeBounds.max) { - endOfBucket = moment.min(endOfBucket, timeBounds.max); - } - const bucketSize = endOfBucket.diff(startOfBucket); - const factor = bucketSize / targetUnitInMs; - - const currentValue = newRow[inputColumnId]; - if (currentValue != null) { - newRow[outputColumnId] = Number(currentValue) / factor; - } - - return newRow; - }), - }; - // reset default moment timezone - moment.tz.setDefault(defaultTimezone); - - return result; - }, - }; - return timeScale; -} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts index b6f5c364e2d046..69b60711e5186a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts @@ -22,9 +22,10 @@ import { import { IndexPatternColumn } from './indexpattern'; import { operationDefinitionMap } from './operations'; import { IndexPattern, IndexPatternPrivateState, IndexPatternLayer } from './types'; -import { OriginalColumn } from './rename_columns'; import { dateHistogramOperation } from './operations/definitions'; +type OriginalColumn = { id: string } & IndexPatternColumn; + function getExpressionForLayer( layer: IndexPatternLayer, indexPattern: IndexPattern, diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx index 27a7659b1c8174..21c68a9fe1d826 100644 --- a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import { metricChart, MetricChart } from './expression'; -import { LensMultiTable } from '../types'; +import { MetricChart, metricChart } from './expression'; +import { MetricConfig } from '../../common/expressions'; import React from 'react'; import { shallow } from 'enzyme'; -import { MetricConfig } from './types'; import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; import { IFieldFormat } from '../../../../../src/plugins/data/public'; +import type { LensMultiTable } from '../../common'; function sampleArgs() { const data: LensMultiTable = { diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.tsx index cf6921b2ca5790..5a1e0d7fb5bdf6 100644 --- a/x-pack/plugins/lens/public/metric_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/expression.tsx @@ -9,75 +9,19 @@ import './expression.scss'; import { I18nProvider } from '@kbn/i18n/react'; import React from 'react'; import ReactDOM from 'react-dom'; -import { - ExpressionFunctionDefinition, +import type { ExpressionRenderDefinition, IInterpreterRenderHandlers, } from '../../../../../src/plugins/expressions/public'; -import { MetricConfig } from './types'; -import { FormatFactory, LensMultiTable } from '../types'; import { AutoScale } from './auto_scale'; import { VisualizationContainer } from '../visualization_container'; import { EmptyPlaceholder } from '../shared_components'; import { LensIconChartMetric } from '../assets/chart_metric'; +import type { FormatFactory } from '../../common'; +import type { MetricChartProps } from '../../common/expressions'; -export interface MetricChartProps { - data: LensMultiTable; - args: MetricConfig; -} - -export interface MetricRender { - type: 'render'; - as: 'lens_metric_chart_renderer'; - value: MetricChartProps; -} - -export const metricChart: ExpressionFunctionDefinition< - 'lens_metric_chart', - LensMultiTable, - Omit, - MetricRender -> = { - name: 'lens_metric_chart', - type: 'render', - help: 'A metric chart', - args: { - title: { - types: ['string'], - help: 'The chart title.', - }, - description: { - types: ['string'], - help: '', - }, - metricTitle: { - types: ['string'], - help: 'The title of the metric shown.', - }, - accessor: { - types: ['string'], - help: 'The column whose value is being displayed', - }, - mode: { - types: ['string'], - options: ['reduced', 'full'], - default: 'full', - help: - 'The display mode of the chart - reduced will only show the metric itself without min size', - }, - }, - inputTypes: ['lens_multitable'], - fn(data, args) { - return { - type: 'render', - as: 'lens_metric_chart_renderer', - value: { - data, - args, - }, - } as MetricRender; - }, -}; +export { metricChart } from '../../common/expressions'; +export type { MetricState, MetricConfig } from '../../common/expressions'; export const getMetricChartRenderer = ( formatFactory: Promise diff --git a/x-pack/plugins/lens/public/metric_visualization/index.ts b/x-pack/plugins/lens/public/metric_visualization/index.ts index c94063ed0bd741..484dc6140ecf22 100644 --- a/x-pack/plugins/lens/public/metric_visualization/index.ts +++ b/x-pack/plugins/lens/public/metric_visualization/index.ts @@ -5,9 +5,10 @@ * 2.0. */ -import { CoreSetup } from 'kibana/public'; -import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; -import { EditorFrameSetup, FormatFactory } from '../types'; +import type { CoreSetup } from 'kibana/public'; +import type { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; +import type { EditorFrameSetup } from '../types'; +import type { FormatFactory } from '../../common'; export interface MetricVisualizationPluginSetupPlugins { expressions: ExpressionsSetup; diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.ts b/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.ts index e7f510f106fffa..d07dccb7701962 100644 --- a/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.ts +++ b/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.ts @@ -6,7 +6,7 @@ */ import { SuggestionRequest, VisualizationSuggestion, TableSuggestion } from '../types'; -import { MetricState } from './types'; +import type { MetricState } from '../../common/expressions'; import { LensIconChartMetric } from '../assets/chart_metric'; /** diff --git a/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts b/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts index 2882d9c4c0246b..2c359d139bb3b7 100644 --- a/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts @@ -6,7 +6,7 @@ */ import { metricVisualization } from './visualization'; -import { MetricState } from './types'; +import type { MetricState } from '../../common/expressions'; import { createMockDatasource, createMockFramePublicAPI } from '../mocks'; import { generateId } from '../id_generator'; import { DatasourcePublicAPI, FramePublicAPI } from '../types'; diff --git a/x-pack/plugins/lens/public/metric_visualization/visualization.tsx b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx index 49565f53bda366..d312030b5a490d 100644 --- a/x-pack/plugins/lens/public/metric_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx @@ -10,7 +10,7 @@ import { Ast } from '@kbn/interpreter/target/common'; import { getSuggestions } from './metric_suggestions'; import { LensIconChartMetric } from '../assets/chart_metric'; import { Visualization, OperationMetadata, DatasourcePublicAPI } from '../types'; -import { MetricState } from './types'; +import type { MetricState } from '../../common/expressions'; const toExpression = ( state: MetricState, diff --git a/x-pack/plugins/lens/public/pie_visualization/expression.tsx b/x-pack/plugins/lens/public/pie_visualization/expression.tsx index 208ce746f4b9d4..ce36f88b2805e9 100644 --- a/x-pack/plugins/lens/public/pie_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/expression.tsx @@ -8,108 +8,18 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { i18n } from '@kbn/i18n'; -import { Position } from '@elastic/charts'; import { I18nProvider } from '@kbn/i18n/react'; -import { +import type { IInterpreterRenderHandlers, ExpressionRenderDefinition, - ExpressionFunctionDefinition, } from 'src/plugins/expressions/public'; -import { LensMultiTable, FormatFactory, LensFilterEvent } from '../types'; -import { PieExpressionProps, PieExpressionArgs } from './types'; +import type { LensFilterEvent } from '../types'; import { PieComponent } from './render_function'; -import { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; +import type { FormatFactory } from '../../common'; +import type { PieExpressionProps } from '../../common/expressions'; +import type { ChartsPluginSetup, PaletteRegistry } from '../../../../../src/plugins/charts/public'; -export interface PieRender { - type: 'render'; - as: 'lens_pie_renderer'; - value: PieExpressionProps; -} - -export const pie: ExpressionFunctionDefinition< - 'lens_pie', - LensMultiTable, - PieExpressionArgs, - PieRender -> = { - name: 'lens_pie', - type: 'render', - help: i18n.translate('xpack.lens.pie.expressionHelpLabel', { - defaultMessage: 'Pie renderer', - }), - args: { - title: { - types: ['string'], - help: 'The chart title.', - }, - description: { - types: ['string'], - help: '', - }, - groups: { - types: ['string'], - multi: true, - help: '', - }, - metric: { - types: ['string'], - help: '', - }, - shape: { - types: ['string'], - options: ['pie', 'donut', 'treemap'], - help: '', - }, - hideLabels: { - types: ['boolean'], - help: '', - }, - numberDisplay: { - types: ['string'], - options: ['hidden', 'percent', 'value'], - help: '', - }, - categoryDisplay: { - types: ['string'], - options: ['default', 'inside', 'hide'], - help: '', - }, - legendDisplay: { - types: ['string'], - options: ['default', 'show', 'hide'], - help: '', - }, - nestedLegend: { - types: ['boolean'], - help: '', - }, - legendPosition: { - types: ['string'], - options: [Position.Top, Position.Right, Position.Bottom, Position.Left], - help: '', - }, - percentDecimals: { - types: ['number'], - help: '', - }, - palette: { - default: `{theme "palette" default={system_palette name="default"} }`, - help: '', - types: ['palette'], - }, - }, - inputTypes: ['lens_multitable'], - fn(data: LensMultiTable, args: PieExpressionArgs) { - return { - type: 'render', - as: 'lens_pie_renderer', - value: { - data, - args, - }, - }; - }, -}; +export { pie } from '../../common/expressions'; export const getPieRenderer = (dependencies: { formatFactory: Promise; diff --git a/x-pack/plugins/lens/public/pie_visualization/index.ts b/x-pack/plugins/lens/public/pie_visualization/index.ts index 9f4a176ef8aa8f..aa74eb5088ea31 100644 --- a/x-pack/plugins/lens/public/pie_visualization/index.ts +++ b/x-pack/plugins/lens/public/pie_visualization/index.ts @@ -5,11 +5,12 @@ * 2.0. */ -import { CoreSetup } from 'src/core/public'; -import { ExpressionsSetup } from 'src/plugins/expressions/public'; -import { EditorFrameSetup, FormatFactory } from '../types'; -import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; -import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; +import type { CoreSetup } from 'src/core/public'; +import type { ExpressionsSetup } from 'src/plugins/expressions/public'; +import type { EditorFrameSetup } from '../types'; +import type { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; +import type { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; +import type { FormatFactory } from '../../common'; export interface PieVisualizationPluginSetupPlugins { editorFrame: EditorFrameSetup; diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx index a3a10b803fcd34..adef7188d12d0a 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx @@ -16,9 +16,9 @@ import { Chart, } from '@elastic/charts'; import { shallow } from 'enzyme'; -import { LensMultiTable } from '../types'; +import type { LensMultiTable } from '../../common'; +import type { PieExpressionArgs } from '../../common/expressions'; import { PieComponent } from './render_function'; -import { PieExpressionArgs } from './types'; import { VisualizationContainer } from '../visualization_container'; import { EmptyPlaceholder } from '../shared_components'; import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks'; diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index b161a81a835f13..ac0aa6cd4b1f18 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -24,10 +24,11 @@ import { ElementClickListener, } from '@elastic/charts'; import { RenderMode } from 'src/plugins/expressions'; -import { FormatFactory, LensFilterEvent } from '../types'; +import type { LensFilterEvent } from '../types'; import { VisualizationContainer } from '../visualization_container'; import { CHART_NAMES, DEFAULT_PERCENT_DECIMALS } from './constants'; -import { PieExpressionProps } from './types'; +import type { FormatFactory } from '../../common'; +import type { PieExpressionProps } from '../../common/expressions'; import { getSliceValue, getFilterContext } from './render_helpers'; import { EmptyPlaceholder } from '../shared_components'; import './visualization.scss'; diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts index a527a3c8645430..36470fa3d74cf8 100644 --- a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts +++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts @@ -8,7 +8,7 @@ import { PaletteOutput } from 'src/plugins/charts/public'; import { DataType, SuggestionRequest } from '../types'; import { suggestions } from './suggestions'; -import { PieVisualizationState } from './types'; +import type { PieVisualizationState } from '../../common/expressions'; describe('suggestions', () => { describe('pie', () => { diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts index 644f0a0cd8aaf8..22be8e3357bbbb 100644 --- a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts +++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts @@ -7,8 +7,8 @@ import { partition } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { SuggestionRequest, VisualizationSuggestion } from '../types'; -import { PieVisualizationState } from './types'; +import type { SuggestionRequest, VisualizationSuggestion } from '../types'; +import type { PieVisualizationState } from '../../common/expressions'; import { CHART_NAMES, MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS } from './constants'; function shouldReject({ table, keptLayerIds }: SuggestionRequest) { diff --git a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts index 14f1fe81c7bd68..7ee26383cebbf2 100644 --- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts @@ -9,7 +9,7 @@ import { Ast } from '@kbn/interpreter/common'; import { PaletteRegistry } from 'src/plugins/charts/public'; import { Operation, DatasourcePublicAPI } from '../types'; import { DEFAULT_PERCENT_DECIMALS } from './constants'; -import { PieVisualizationState } from './types'; +import type { PieVisualizationState } from '../../common/expressions'; export function toExpression( state: PieVisualizationState, diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx index a2596f7ce1e0ff..5da69e47f861cd 100644 --- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx @@ -15,10 +15,10 @@ import { EuiRange, EuiHorizontalRule, } from '@elastic/eui'; -import { Position } from '@elastic/charts'; -import { PaletteRegistry } from 'src/plugins/charts/public'; +import type { Position } from '@elastic/charts'; +import type { PaletteRegistry } from 'src/plugins/charts/public'; import { DEFAULT_PERCENT_DECIMALS } from './constants'; -import { PieVisualizationState, SharedPieLayerState } from './types'; +import type { PieVisualizationState, SharedPieLayerState } from '../../common/expressions'; import { VisualizationDimensionEditorProps, VisualizationToolbarProps } from '../types'; import { ToolbarPopover, LegendSettingsPopover, useDebouncedValue } from '../shared_components'; import { PalettePicker } from '../shared_components'; diff --git a/x-pack/plugins/lens/public/pie_visualization/visualization.test.ts b/x-pack/plugins/lens/public/pie_visualization/visualization.test.ts index 2a961cef315bf2..07a4161e7d239b 100644 --- a/x-pack/plugins/lens/public/pie_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/pie_visualization/visualization.test.ts @@ -6,7 +6,7 @@ */ import { getPieVisualization } from './visualization'; -import { PieVisualizationState } from './types'; +import type { PieVisualizationState } from '../../common/expressions'; import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks'; jest.mock('../id_generator'); diff --git a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx index c82fdb2766f7eb..5d75d82220d1fe 100644 --- a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx @@ -9,10 +9,10 @@ import React from 'react'; import { render } from 'react-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; -import { PaletteRegistry } from 'src/plugins/charts/public'; -import { Visualization, OperationMetadata, AccessorConfig } from '../types'; +import type { PaletteRegistry } from 'src/plugins/charts/public'; +import type { Visualization, OperationMetadata, AccessorConfig } from '../types'; import { toExpression, toPreviewExpression } from './to_expression'; -import { PieLayerState, PieVisualizationState } from './types'; +import type { PieLayerState, PieVisualizationState } from '../../common/expressions'; import { suggestions } from './suggestions'; import { CHART_NAMES, MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS } from './constants'; import { DimensionEditor, PieToolbar } from './toolbar'; diff --git a/x-pack/plugins/lens/public/shared_components/coloring/color_stops.tsx b/x-pack/plugins/lens/public/shared_components/coloring/color_stops.tsx index 37197b232ddf55..1431e6ad135bef 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/color_stops.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/color_stops.tsx @@ -22,7 +22,7 @@ import useUnmount from 'react-use/lib/useUnmount'; import { DEFAULT_COLOR } from './constants'; import { getDataMinMax, getStepValue, isValidColor } from './utils'; import { TooltipWrapper, useDebouncedValue } from '../index'; -import { ColorStop, CustomPaletteParams } from './types'; +import type { ColorStop, CustomPaletteParams } from '../../../common'; const idGeneratorFn = htmlIdGenerator(); diff --git a/x-pack/plugins/lens/public/shared_components/coloring/constants.ts b/x-pack/plugins/lens/public/shared_components/coloring/constants.ts index 5e6fc207656ac3..29b50d3aee22d8 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/constants.ts +++ b/x-pack/plugins/lens/public/shared_components/coloring/constants.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RequiredPaletteParamTypes } from './types'; +import type { RequiredPaletteParamTypes } from '../../../common'; export const DEFAULT_PALETTE_NAME = 'positive'; export const FIXED_PROGRESSION = 'fixed' as const; diff --git a/x-pack/plugins/lens/public/shared_components/coloring/index.ts b/x-pack/plugins/lens/public/shared_components/coloring/index.ts index 0ad831603ab95f..7cbf79ac43b1e7 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/index.ts +++ b/x-pack/plugins/lens/public/shared_components/coloring/index.ts @@ -8,6 +8,5 @@ export { CustomizablePalette } from './palette_configuration'; export { PalettePanelContainer } from './palette_panel_container'; export { CustomStops } from './color_stops'; -export * from './types'; export * from './utils'; export * from './constants'; diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.test.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.test.tsx index e36e817b3d7144..ad1755bdbe85cb 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.test.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.test.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { EuiColorPalettePickerPaletteProps } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test/jest'; import { chartPluginMock } from 'src/plugins/charts/public/mocks'; -import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; +import type { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; import { ReactWrapper } from 'enzyme'; -import { CustomPaletteParams } from './types'; +import type { CustomPaletteParams } from '../../../common'; import { applyPaletteParams } from './utils'; import { CustomizablePalette } from './palette_configuration'; diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.tsx index 993bf4f78dd20b..bc6a590db0cb7c 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.tsx @@ -6,7 +6,7 @@ */ import React, { FC } from 'react'; -import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; +import type { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; import { EuiFormRow, htmlIdGenerator, @@ -26,7 +26,7 @@ import './palette_configuration.scss'; import { CustomStops } from './color_stops'; import { defaultPaletteParams, CUSTOM_PALETTE, DEFAULT_COLOR_STEPS } from './constants'; -import { CustomPaletteParams, RequiredPaletteParamTypes } from './types'; +import type { CustomPaletteParams, RequiredPaletteParamTypes } from '../../../common'; import { getColorStops, getPaletteStops, diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx index 1371fbe73ef845..583d6e25ed4e28 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx @@ -7,6 +7,7 @@ import './palette_panel_container.scss'; +import { i18n } from '@kbn/i18n'; import React, { useState, useEffect, MutableRefObject } from 'react'; import { EuiFlyoutHeader, @@ -21,8 +22,6 @@ import { EuiPortal, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - export function PalettePanelContainer({ isOpen, handleClose, diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_picker.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_picker.tsx index 164ed9bf067a66..2a415cd178925b 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_picker.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_picker.tsx @@ -13,9 +13,9 @@ import { DEFAULT_COLOR_STEPS, FIXED_PROGRESSION, defaultPaletteParams, -} from '../../shared_components/coloring/constants'; -import { CustomPaletteParams } from '../../shared_components/coloring/types'; -import { getStopsForFixedMode } from '../../shared_components/coloring/utils'; +} from './constants'; +import type { CustomPaletteParams } from '../../../common'; +import { getStopsForFixedMode } from './utils'; function getCustomPaletteConfig( palettes: PaletteRegistry, diff --git a/x-pack/plugins/lens/public/shared_components/coloring/types.ts b/x-pack/plugins/lens/public/shared_components/coloring/types.ts deleted file mode 100644 index d9a8edf0ccb62b..00000000000000 --- a/x-pack/plugins/lens/public/shared_components/coloring/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -export interface ColorStop { - color: string; - stop: number; -} - -export interface CustomPaletteParams { - name?: string; - reverse?: boolean; - rangeType?: 'number' | 'percent'; - continuity?: 'above' | 'below' | 'all' | 'none'; - progression?: 'fixed'; - rangeMin?: number; - rangeMax?: number; - stops?: ColorStop[]; - colorStops?: ColorStop[]; - steps?: number; -} - -export type RequiredPaletteParamTypes = Required; diff --git a/x-pack/plugins/lens/public/shared_components/coloring/utils.ts b/x-pack/plugins/lens/public/shared_components/coloring/utils.ts index 9c42ce5013b9b9..8cd0a6cf49001d 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/utils.ts +++ b/x-pack/plugins/lens/public/shared_components/coloring/utils.ts @@ -9,7 +9,7 @@ import chroma from 'chroma-js'; import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; import { euiLightVars, euiDarkVars } from '@kbn/ui-shared-deps/theme'; import { isColorDark } from '@elastic/eui'; -import { Datatable } from 'src/plugins/expressions/public'; +import type { Datatable } from 'src/plugins/expressions/public'; import { CUSTOM_PALETTE, defaultPaletteParams, @@ -17,7 +17,7 @@ import { DEFAULT_MAX_STOP, DEFAULT_MIN_STOP, } from './constants'; -import { CustomPaletteParams, ColorStop } from './types'; +import type { CustomPaletteParams, ColorStop } from '../../../common'; /** * Some name conventions here: diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index cb47dcf6ec3889..3d87d234ae9866 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -16,11 +16,10 @@ import { ExpressionRendererEvent, IInterpreterRenderHandlers, Datatable, - SerializedFieldFormat, } from '../../../../src/plugins/expressions/public'; import { DraggingIdentifier, DragDropIdentifier, DragContextState } from './drag_drop'; import { DateRange } from '../common'; -import { Query, Filter, IFieldFormat } from '../../../../src/plugins/data/public'; +import { Query, Filter } from '../../../../src/plugins/data/public'; import { VisualizeFieldContext } from '../../../../src/plugins/ui_actions/public'; import { RangeSelectContext, ValueClickContext } from '../../../../src/plugins/embeddable/public'; import { @@ -37,8 +36,6 @@ import { UiActionsStart } from '../../../../src/plugins/ui_actions/public'; export type ErrorCallback = (e: { message: string }) => void; -export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat; - export interface PublicAPIProps { state: T; layerId: string; @@ -387,15 +384,6 @@ export interface OperationMetadata { // introduce a raw document datasource, this should be considered here. } -export interface LensMultiTable { - type: 'lens_multitable'; - tables: Record; - dateRange?: { - fromDate: Date; - toDate: Date; - }; -} - export interface VisualizationConfigProps { layerId: string; frame: Pick; diff --git a/x-pack/plugins/lens/public/xy_visualization/axes_configuration.test.ts b/x-pack/plugins/lens/public/xy_visualization/axes_configuration.test.ts index b82afeb1b7d1df..873827700d6e8b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/axes_configuration.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/axes_configuration.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LayerArgs } from './types'; +import { LayerArgs } from '../../common/expressions'; import { Datatable } from '../../../../../src/plugins/expressions/public'; import { getAxesConfiguration } from './axes_configuration'; diff --git a/x-pack/plugins/lens/public/xy_visualization/axes_configuration.ts b/x-pack/plugins/lens/public/xy_visualization/axes_configuration.ts index 58a80ad0fed378..83d86eb410b195 100644 --- a/x-pack/plugins/lens/public/xy_visualization/axes_configuration.ts +++ b/x-pack/plugins/lens/public/xy_visualization/axes_configuration.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { AxisExtentConfig, XYLayerConfig } from './types'; +import { FormatFactory } from '../../common'; +import { AxisExtentConfig, XYLayerConfig } from '../../common/expressions'; import { Datatable, SerializedFieldFormat } from '../../../../../src/plugins/expressions/public'; import { IFieldFormat } from '../../../../../src/plugins/data/public'; @@ -33,7 +34,7 @@ export function getAxesConfiguration( layers: XYLayerConfig[], shouldRotate: boolean, tables?: Record, - formatFactory?: (mapping: SerializedFieldFormat) => IFieldFormat + formatFactory?: FormatFactory ): GroupsConfiguration { const series: { auto: FormattedMetric[]; left: FormattedMetric[]; right: FormattedMetric[] } = { auto: [], diff --git a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx index a0d1dae2145d5a..52098ab92cad65 100644 --- a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx @@ -20,7 +20,7 @@ import { EuiFieldNumber, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { XYLayerConfig, AxesSettingsConfig, AxisExtentConfig } from './types'; +import { XYLayerConfig, AxesSettingsConfig, AxisExtentConfig } from '../../common/expressions'; import { ToolbarPopover, useDebouncedValue } from '../shared_components'; import { isHorizontalChart } from './state_helpers'; import { EuiIconAxisBottom } from '../assets/axis_bottom'; diff --git a/x-pack/plugins/lens/public/xy_visualization/color_assignment.test.ts b/x-pack/plugins/lens/public/xy_visualization/color_assignment.test.ts index 04a64d7ff5c936..390eded97d705b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/color_assignment.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/color_assignment.test.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { FormatFactory, LensMultiTable } from '../types'; import { getColorAssignments } from './color_assignment'; -import { LayerArgs } from './types'; +import type { FormatFactory, LensMultiTable } from '../../common'; +import type { LayerArgs } from '../../common/expressions'; describe('color_assignment', () => { const layers: LayerArgs[] = [ diff --git a/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts b/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts index ef0c350f209619..1e00d821d9b30f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts +++ b/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts @@ -6,11 +6,12 @@ */ import { uniq, mapValues } from 'lodash'; -import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; -import { Datatable } from 'src/plugins/expressions'; -import { AccessorConfig, FormatFactory, FramePublicAPI } from '../types'; +import type { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; +import type { Datatable } from 'src/plugins/expressions'; +import type { AccessorConfig, FramePublicAPI } from '../types'; import { getColumnToLabelMap } from './state_helpers'; -import { XYLayerConfig } from './types'; +import type { FormatFactory } from '../../common'; +import type { XYLayerConfig } from '../../common/expressions'; const isPrimitive = (value: unknown): boolean => value != null && typeof value !== 'object'; diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx index b018e62f1fd8f7..3a28f137f93bd3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -22,27 +22,22 @@ import { LayoutDirection, } from '@elastic/charts'; import { PaletteOutput } from 'src/plugins/charts/public'; +import { calculateMinInterval, XYChart, XYChartRenderProps, xyChart } from './expression'; +import type { LensMultiTable } from '../../common'; import { - calculateMinInterval, - xyChart, - XYChart, - XYChartProps, - XYChartRenderProps, -} from './expression'; -import { LensMultiTable } from '../types'; -import { Datatable, DatatableRow } from '../../../../../src/plugins/expressions/public'; -import React from 'react'; -import { shallow } from 'enzyme'; -import { + layerConfig, + legendConfig, + tickLabelsConfig, + gridlinesConfig, XYArgs, LegendConfig, - legendConfig, - layerConfig, LayerArgs, AxesSettingsConfig, - tickLabelsConfig, - gridlinesConfig, -} from './types'; + XYChartProps, +} from '../../common/expressions'; +import { Datatable, DatatableRow } from '../../../../../src/plugins/expressions/public'; +import React from 'react'; +import { shallow } from 'enzyme'; import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; import { mountWithIntl } from '@kbn/test/jest'; import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks'; diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 7c767cd1d1b04d..4cd63c5747e871 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -30,8 +30,7 @@ import { LabelOverflowConstraint, } from '@elastic/charts'; import { I18nProvider } from '@kbn/i18n/react'; -import { - ExpressionFunctionDefinition, +import type { ExpressionRenderDefinition, Datatable, DatatableRow, @@ -39,24 +38,20 @@ import { import { IconType } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { RenderMode } from 'src/plugins/expressions'; -import { - LensMultiTable, - FormatFactory, - ILensInterpreterRenderHandlers, - LensFilterEvent, - LensBrushEvent, -} from '../types'; -import { XYArgs, SeriesType, visualizationTypes, LayerArgs } from './types'; +import type { ILensInterpreterRenderHandlers, LensFilterEvent, LensBrushEvent } from '../types'; +import type { LensMultiTable, FormatFactory } from '../../common'; +import { LayerArgs, SeriesType, XYChartProps } from '../../common/expressions'; +import { visualizationTypes } from './types'; import { VisualizationContainer } from '../visualization_container'; import { isHorizontalChart, getSeriesColor } from './state_helpers'; -import { ExpressionValueSearchContext, search } from '../../../../../src/plugins/data/public'; +import { search } from '../../../../../src/plugins/data/public'; import { ChartsPluginSetup, PaletteRegistry, SeriesLayer, } from '../../../../../src/plugins/charts/public'; import { EmptyPlaceholder } from '../shared_components'; -import { fittingFunctionDefinitions, getFitOptions } from './fitting_functions'; +import { getFitOptions } from './fitting_functions'; import { getAxesConfiguration, GroupsConfiguration, validateExtent } from './axes_configuration'; import { getColorAssignments } from './color_assignment'; import { getXDomain, XyEndzones } from './x_domain'; @@ -76,16 +71,16 @@ type SeriesSpec = InferPropType & InferPropType & InferPropType; -export interface XYChartProps { - data: LensMultiTable; - args: XYArgs; -} - -export interface XYRender { - type: 'render'; - as: 'lens_xy_chart_renderer'; - value: XYChartProps; -} +export { + legendConfig, + yAxisConfig, + tickLabelsConfig, + gridlinesConfig, + axisTitlesVisibilityConfig, + axisExtentConfig, + layerConfig, + xyChart, +} from '../../common/expressions'; export type XYChartRenderProps = XYChartProps & { chartsThemeService: ChartsPluginSetup['theme']; @@ -99,139 +94,6 @@ export type XYChartRenderProps = XYChartProps & { syncColors: boolean; }; -export const xyChart: ExpressionFunctionDefinition< - 'lens_xy_chart', - LensMultiTable | ExpressionValueSearchContext | null, - XYArgs, - XYRender -> = { - name: 'lens_xy_chart', - type: 'render', - inputTypes: ['lens_multitable', 'kibana_context', 'null'], - help: i18n.translate('xpack.lens.xyChart.help', { - defaultMessage: 'An X/Y chart', - }), - args: { - title: { - types: ['string'], - help: 'The chart title.', - }, - description: { - types: ['string'], - help: '', - }, - xTitle: { - types: ['string'], - help: i18n.translate('xpack.lens.xyChart.xTitle.help', { - defaultMessage: 'X axis title', - }), - }, - yTitle: { - types: ['string'], - help: i18n.translate('xpack.lens.xyChart.yLeftTitle.help', { - defaultMessage: 'Y left axis title', - }), - }, - yRightTitle: { - types: ['string'], - help: i18n.translate('xpack.lens.xyChart.yRightTitle.help', { - defaultMessage: 'Y right axis title', - }), - }, - yLeftExtent: { - types: ['lens_xy_axisExtentConfig'], - help: i18n.translate('xpack.lens.xyChart.yLeftExtent.help', { - defaultMessage: 'Y left axis extents', - }), - }, - yRightExtent: { - types: ['lens_xy_axisExtentConfig'], - help: i18n.translate('xpack.lens.xyChart.yRightExtent.help', { - defaultMessage: 'Y right axis extents', - }), - }, - legend: { - types: ['lens_xy_legendConfig'], - help: i18n.translate('xpack.lens.xyChart.legend.help', { - defaultMessage: 'Configure the chart legend.', - }), - }, - fittingFunction: { - types: ['string'], - options: [...fittingFunctionDefinitions.map(({ id }) => id)], - help: i18n.translate('xpack.lens.xyChart.fittingFunction.help', { - defaultMessage: 'Define how missing values are treated', - }), - }, - valueLabels: { - types: ['string'], - options: ['hide', 'inside'], - help: '', - }, - tickLabelsVisibilitySettings: { - types: ['lens_xy_tickLabelsConfig'], - help: i18n.translate('xpack.lens.xyChart.tickLabelsSettings.help', { - defaultMessage: 'Show x and y axes tick labels', - }), - }, - gridlinesVisibilitySettings: { - types: ['lens_xy_gridlinesConfig'], - help: i18n.translate('xpack.lens.xyChart.gridlinesSettings.help', { - defaultMessage: 'Show x and y axes gridlines', - }), - }, - axisTitlesVisibilitySettings: { - types: ['lens_xy_axisTitlesVisibilityConfig'], - help: i18n.translate('xpack.lens.xyChart.axisTitlesSettings.help', { - defaultMessage: 'Show x and y axes titles', - }), - }, - layers: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - types: ['lens_xy_layer'] as any, - help: 'Layers of visual series', - multi: true, - }, - curveType: { - types: ['string'], - options: ['LINEAR', 'CURVE_MONOTONE_X'], - help: i18n.translate('xpack.lens.xyChart.curveType.help', { - defaultMessage: 'Define how curve type is rendered for a line chart', - }), - }, - fillOpacity: { - types: ['number'], - help: i18n.translate('xpack.lens.xyChart.fillOpacity.help', { - defaultMessage: 'Define the area chart fill opacity', - }), - }, - hideEndzones: { - types: ['boolean'], - default: false, - help: i18n.translate('xpack.lens.xyChart.hideEndzones.help', { - defaultMessage: 'Hide endzone markers for partial data', - }), - }, - valuesInLegend: { - types: ['boolean'], - default: false, - help: i18n.translate('xpack.lens.xyChart.valuesInLegend.help', { - defaultMessage: 'Show values in legend', - }), - }, - }, - fn(data: LensMultiTable, args: XYArgs) { - return { - type: 'render', - as: 'lens_xy_chart_renderer', - value: { - data, - args, - }, - }; - }, -}; - export function calculateMinInterval({ args: { layers }, data }: XYChartProps) { const filteredLayers = getFilteredLayers(layers, data); if (filteredLayers.length === 0) return; diff --git a/x-pack/plugins/lens/public/xy_visualization/fitting_functions.ts b/x-pack/plugins/lens/public/xy_visualization/fitting_functions.ts index a1f8ad1fa259ad..0b0878dfe96843 100644 --- a/x-pack/plugins/lens/public/xy_visualization/fitting_functions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/fitting_functions.ts @@ -6,57 +6,7 @@ */ import { Fit } from '@elastic/charts'; -import { i18n } from '@kbn/i18n'; - -export type FittingFunction = typeof fittingFunctionDefinitions[number]['id']; - -export const fittingFunctionDefinitions = [ - { - id: 'None', - title: i18n.translate('xpack.lens.fittingFunctionsTitle.none', { - defaultMessage: 'Hide', - }), - description: i18n.translate('xpack.lens.fittingFunctionsDescription.none', { - defaultMessage: 'Do not fill gaps', - }), - }, - { - id: 'Zero', - title: i18n.translate('xpack.lens.fittingFunctionsTitle.zero', { - defaultMessage: 'Zero', - }), - description: i18n.translate('xpack.lens.fittingFunctionsDescription.zero', { - defaultMessage: 'Fill gaps with zeros', - }), - }, - { - id: 'Linear', - title: i18n.translate('xpack.lens.fittingFunctionsTitle.linear', { - defaultMessage: 'Linear', - }), - description: i18n.translate('xpack.lens.fittingFunctionsDescription.linear', { - defaultMessage: 'Fill gaps with a line', - }), - }, - { - id: 'Carry', - title: i18n.translate('xpack.lens.fittingFunctionsTitle.carry', { - defaultMessage: 'Last', - }), - description: i18n.translate('xpack.lens.fittingFunctionsDescription.carry', { - defaultMessage: 'Fill gaps with the last value', - }), - }, - { - id: 'Lookahead', - title: i18n.translate('xpack.lens.fittingFunctionsTitle.lookahead', { - defaultMessage: 'Next', - }), - description: i18n.translate('xpack.lens.fittingFunctionsDescription.lookahead', { - defaultMessage: 'Fill gaps with the next value', - }), - }, -] as const; +import { FittingFunction } from '../../common/expressions'; export function getFitEnum(fittingFunction?: FittingFunction) { if (fittingFunction) { diff --git a/x-pack/plugins/lens/public/xy_visualization/get_legend_action.test.tsx b/x-pack/plugins/lens/public/xy_visualization/get_legend_action.test.tsx index e4edfe918a242d..e3489ae7808af0 100644 --- a/x-pack/plugins/lens/public/xy_visualization/get_legend_action.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/get_legend_action.test.tsx @@ -10,8 +10,8 @@ import { LegendActionProps, SeriesIdentifier } from '@elastic/charts'; import { EuiPopover } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test/jest'; import { ComponentType, ReactWrapper } from 'enzyme'; -import type { LayerArgs } from './types'; -import type { LensMultiTable } from '../types'; +import type { LensMultiTable } from '../../common'; +import type { LayerArgs } from '../../common/expressions'; import { getLegendAction } from './get_legend_action'; import { LegendActionPopover } from '../shared_components'; diff --git a/x-pack/plugins/lens/public/xy_visualization/get_legend_action.tsx b/x-pack/plugins/lens/public/xy_visualization/get_legend_action.tsx index c99bf948d6e374..0603328ee5bb3a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/get_legend_action.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/get_legend_action.tsx @@ -7,8 +7,9 @@ import React from 'react'; import type { LegendAction, XYChartSeriesIdentifier } from '@elastic/charts'; -import type { LayerArgs } from './types'; -import type { LensMultiTable, LensFilterEvent, FormatFactory } from '../types'; +import type { LensFilterEvent } from '../types'; +import type { LensMultiTable, FormatFactory } from '../../common'; +import type { LayerArgs } from '../../common/expressions'; import { LegendActionPopover } from '../shared_components'; export const getLegendAction = ( diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts index f29d0f92802465..de9ecd0b694e47 100644 --- a/x-pack/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/plugins/lens/public/xy_visualization/index.ts @@ -5,12 +5,13 @@ * 2.0. */ -import { CoreSetup } from 'kibana/public'; -import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; -import { EditorFrameSetup, FormatFactory } from '../types'; -import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; -import { LensPluginStartDependencies } from '../plugin'; +import type { CoreSetup } from 'kibana/public'; +import type { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; +import type { EditorFrameSetup } from '../types'; +import type { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; +import type { LensPluginStartDependencies } from '../plugin'; import { getTimeZone } from '../utils'; +import type { FormatFactory } from '../../common'; export interface XyVisualizationPluginSetupPlugins { expressions: ExpressionsSetup; diff --git a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts index aa8dede62f5667..e3b16f5981f88f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts +++ b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts @@ -6,8 +6,9 @@ */ import { EuiIconType } from '@elastic/eui/src/components/icon/icon'; -import { FramePublicAPI, DatasourcePublicAPI } from '../types'; -import { SeriesType, visualizationTypes, XYLayerConfig, YConfig, ValidLayer } from './types'; +import type { FramePublicAPI, DatasourcePublicAPI } from '../types'; +import type { SeriesType, XYLayerConfig, YConfig, ValidLayer } from '../../common/expressions'; +import { visualizationTypes } from './types'; export function isHorizontalSeries(seriesType: SeriesType) { return ( diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index c89a5e81e35d01..b588cd5592a436 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -8,9 +8,10 @@ import { Ast } from '@kbn/interpreter/common'; import { ScaleType } from '@elastic/charts'; import { PaletteRegistry } from 'src/plugins/charts/public'; -import { State, ValidLayer, XYLayerConfig } from './types'; +import { State } from './types'; import { OperationMetadata, DatasourcePublicAPI } from '../types'; import { getColumnToLabelMap } from './state_helpers'; +import { ValidLayer, XYLayerConfig } from '../../common/expressions'; export const getSortedAccessors = (datasource: DatasourcePublicAPI, layer: XYLayerConfig) => { const originalOrder = datasource diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index 609622186af20a..dcc147b4170a09 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { Position, VerticalAlignment, HorizontalAlignment } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; -import { PaletteOutput } from 'src/plugins/charts/public'; -import { ArgumentType, ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { LensIconChartArea } from '../assets/chart_area'; import { LensIconChartAreaStacked } from '../assets/chart_area_stacked'; import { LensIconChartAreaPercentage } from '../assets/chart_area_percentage'; @@ -21,499 +18,16 @@ import { LensIconChartBarHorizontalPercentage } from '../assets/chart_bar_horizo import { LensIconChartLine } from '../assets/chart_line'; import { VisualizationType } from '../types'; -import { FittingFunction } from './fitting_functions'; - -export interface LegendConfig { - /** - * Flag whether the legend should be shown. If there is just a single series, it will be hidden - */ - isVisible: boolean; - /** - * Position of the legend relative to the chart - */ - position: Position; - /** - * Flag whether the legend should be shown even with just a single series - */ - showSingleSeries?: boolean; - /** - * Flag whether the legend is inside the chart - */ - isInside?: boolean; - /** - * Horizontal Alignment of the legend when it is set inside chart - */ - horizontalAlignment?: HorizontalAlignment; - /** - * Vertical Alignment of the legend when it is set inside chart - */ - verticalAlignment?: VerticalAlignment; - /** - * Number of columns when legend is set inside chart - */ - floatingColumns?: number; -} - -type LegendConfigResult = LegendConfig & { type: 'lens_xy_legendConfig' }; - -export const legendConfig: ExpressionFunctionDefinition< - 'lens_xy_legendConfig', - null, +import { + SeriesType, + ValueLabelConfig, LegendConfig, - LegendConfigResult -> = { - name: 'lens_xy_legendConfig', - aliases: [], - type: 'lens_xy_legendConfig', - help: `Configure the xy chart's legend`, - inputTypes: ['null'], - args: { - isVisible: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.isVisible.help', { - defaultMessage: 'Specifies whether or not the legend is visible.', - }), - }, - position: { - types: ['string'], - options: [Position.Top, Position.Right, Position.Bottom, Position.Left], - help: i18n.translate('xpack.lens.xyChart.position.help', { - defaultMessage: 'Specifies the legend position.', - }), - }, - showSingleSeries: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.showSingleSeries.help', { - defaultMessage: 'Specifies whether a legend with just a single entry should be shown', - }), - }, - isInside: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.isInside.help', { - defaultMessage: 'Specifies whether a legend is inside the chart', - }), - }, - horizontalAlignment: { - types: ['string'], - options: [HorizontalAlignment.Right, HorizontalAlignment.Left], - help: i18n.translate('xpack.lens.xyChart.horizontalAlignment.help', { - defaultMessage: - 'Specifies the horizontal alignment of the legend when it is displayed inside chart.', - }), - }, - verticalAlignment: { - types: ['string'], - options: [VerticalAlignment.Top, VerticalAlignment.Bottom], - help: i18n.translate('xpack.lens.xyChart.verticalAlignment.help', { - defaultMessage: - 'Specifies the vertical alignment of the legend when it is displayed inside chart.', - }), - }, - floatingColumns: { - types: ['number'], - help: i18n.translate('xpack.lens.xyChart.floatingColumns.help', { - defaultMessage: 'Specifies the number of columns when legend is displayed inside chart.', - }), - }, - }, - fn: function fn(input: unknown, args: LegendConfig) { - return { - type: 'lens_xy_legendConfig', - ...args, - }; - }, -}; - -export interface AxesSettingsConfig { - x: boolean; - yLeft: boolean; - yRight: boolean; -} - -type TickLabelsConfigResult = AxesSettingsConfig & { type: 'lens_xy_tickLabelsConfig' }; - -export const tickLabelsConfig: ExpressionFunctionDefinition< - 'lens_xy_tickLabelsConfig', - null, - AxesSettingsConfig, - TickLabelsConfigResult -> = { - name: 'lens_xy_tickLabelsConfig', - aliases: [], - type: 'lens_xy_tickLabelsConfig', - help: `Configure the xy chart's tick labels appearance`, - inputTypes: ['null'], - args: { - x: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.xAxisTickLabels.help', { - defaultMessage: 'Specifies whether or not the tick labels of the x-axis are visible.', - }), - }, - yLeft: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yLeftAxisTickLabels.help', { - defaultMessage: 'Specifies whether or not the tick labels of the left y-axis are visible.', - }), - }, - yRight: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yRightAxisTickLabels.help', { - defaultMessage: 'Specifies whether or not the tick labels of the right y-axis are visible.', - }), - }, - }, - fn: function fn(input: unknown, args: AxesSettingsConfig) { - return { - type: 'lens_xy_tickLabelsConfig', - ...args, - }; - }, -}; - -type GridlinesConfigResult = AxesSettingsConfig & { type: 'lens_xy_gridlinesConfig' }; - -export const gridlinesConfig: ExpressionFunctionDefinition< - 'lens_xy_gridlinesConfig', - null, - AxesSettingsConfig, - GridlinesConfigResult -> = { - name: 'lens_xy_gridlinesConfig', - aliases: [], - type: 'lens_xy_gridlinesConfig', - help: `Configure the xy chart's gridlines appearance`, - inputTypes: ['null'], - args: { - x: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.xAxisGridlines.help', { - defaultMessage: 'Specifies whether or not the gridlines of the x-axis are visible.', - }), - }, - yLeft: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yLeftAxisgridlines.help', { - defaultMessage: 'Specifies whether or not the gridlines of the left y-axis are visible.', - }), - }, - yRight: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yRightAxisgridlines.help', { - defaultMessage: 'Specifies whether or not the gridlines of the right y-axis are visible.', - }), - }, - }, - fn: function fn(input: unknown, args: AxesSettingsConfig) { - return { - type: 'lens_xy_gridlinesConfig', - ...args, - }; - }, -}; - -type AxisTitlesVisibilityConfigResult = AxesSettingsConfig & { - type: 'lens_xy_axisTitlesVisibilityConfig'; -}; - -export const axisTitlesVisibilityConfig: ExpressionFunctionDefinition< - 'lens_xy_axisTitlesVisibilityConfig', - null, - AxesSettingsConfig, - AxisTitlesVisibilityConfigResult -> = { - name: 'lens_xy_axisTitlesVisibilityConfig', - aliases: [], - type: 'lens_xy_axisTitlesVisibilityConfig', - help: `Configure the xy chart's axis titles appearance`, - inputTypes: ['null'], - args: { - x: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.xAxisTitle.help', { - defaultMessage: 'Specifies whether or not the title of the x-axis are visible.', - }), - }, - yLeft: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yLeftAxisTitle.help', { - defaultMessage: 'Specifies whether or not the title of the left y-axis are visible.', - }), - }, - yRight: { - types: ['boolean'], - help: i18n.translate('xpack.lens.xyChart.yRightAxisTitle.help', { - defaultMessage: 'Specifies whether or not the title of the right y-axis are visible.', - }), - }, - }, - fn: function fn(input: unknown, args: AxesSettingsConfig) { - return { - type: 'lens_xy_axisTitlesVisibilityConfig', - ...args, - }; - }, -}; - -export interface AxisExtentConfig { - mode: 'full' | 'dataBounds' | 'custom'; - lowerBound?: number; - upperBound?: number; -} - -export const axisExtentConfig: ExpressionFunctionDefinition< - 'lens_xy_axisExtentConfig', - null, AxisExtentConfig, - AxisExtentConfigResult -> = { - name: 'lens_xy_axisExtentConfig', - aliases: [], - type: 'lens_xy_axisExtentConfig', - help: `Configure the xy chart's axis extents`, - inputTypes: ['null'], - args: { - mode: { - types: ['string'], - options: ['full', 'dataBounds', 'custom'], - help: i18n.translate('xpack.lens.xyChart.extentMode.help', { - defaultMessage: 'The extent mode', - }), - }, - lowerBound: { - types: ['number'], - help: i18n.translate('xpack.lens.xyChart.extentMode.help', { - defaultMessage: 'The extent mode', - }), - }, - upperBound: { - types: ['number'], - help: i18n.translate('xpack.lens.xyChart.extentMode.help', { - defaultMessage: 'The extent mode', - }), - }, - }, - fn: function fn(input: unknown, args: AxisExtentConfig) { - return { - type: 'lens_xy_axisExtentConfig', - ...args, - }; - }, -}; - -export type AxisExtentConfigResult = AxisExtentConfig & { type: 'lens_xy_axisExtentConfig' }; - -interface AxisConfig { - title: string; - hide?: boolean; -} - -const axisConfig: { [key in keyof AxisConfig]: ArgumentType } = { - title: { - types: ['string'], - help: i18n.translate('xpack.lens.xyChart.title.help', { - defaultMessage: 'The axis title', - }), - }, - hide: { - types: ['boolean'], - default: false, - help: 'Show / hide axis', - }, -}; - -type YConfigResult = YConfig & { type: 'lens_xy_yConfig' }; - -export const yAxisConfig: ExpressionFunctionDefinition< - 'lens_xy_yConfig', - null, - YConfig, - YConfigResult -> = { - name: 'lens_xy_yConfig', - aliases: [], - type: 'lens_xy_yConfig', - help: `Configure the behavior of a xy chart's y axis metric`, - inputTypes: ['null'], - args: { - forAccessor: { - types: ['string'], - help: 'The accessor this configuration is for', - }, - axisMode: { - types: ['string'], - options: ['auto', 'left', 'right'], - help: 'The axis mode of the metric', - }, - color: { - types: ['string'], - help: 'The color of the series', - }, - }, - fn: function fn(input: unknown, args: YConfig) { - return { - type: 'lens_xy_yConfig', - ...args, - }; - }, -}; - -type LayerConfigResult = LayerArgs & { type: 'lens_xy_layer' }; - -export const layerConfig: ExpressionFunctionDefinition< - 'lens_xy_layer', - null, - LayerArgs, - LayerConfigResult -> = { - name: 'lens_xy_layer', - aliases: [], - type: 'lens_xy_layer', - help: `Configure a layer in the xy chart`, - inputTypes: ['null'], - args: { - ...axisConfig, - layerId: { - types: ['string'], - help: '', - }, - xAccessor: { - types: ['string'], - help: '', - }, - seriesType: { - types: ['string'], - options: [ - 'bar', - 'line', - 'area', - 'bar_stacked', - 'area_stacked', - 'bar_percentage_stacked', - 'area_percentage_stacked', - ], - help: 'The type of chart to display.', - }, - xScaleType: { - options: ['ordinal', 'linear', 'time'], - help: 'The scale type of the x axis', - default: 'ordinal', - }, - isHistogram: { - types: ['boolean'], - default: false, - help: 'Whether to layout the chart as a histogram', - }, - yScaleType: { - options: ['log', 'sqrt', 'linear', 'time'], - help: 'The scale type of the y axes', - default: 'linear', - }, - splitAccessor: { - types: ['string'], - help: 'The column to split by', - multi: false, - }, - accessors: { - types: ['string'], - help: 'The columns to display on the y axis.', - multi: true, - }, - yConfig: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - types: ['lens_xy_yConfig' as any], - help: 'Additional configuration for y axes', - multi: true, - }, - columnToLabel: { - types: ['string'], - help: 'JSON key-value pairs of column ID to label', - }, - palette: { - default: `{theme "palette" default={system_palette name="default"} }`, - help: '', - types: ['palette'], - }, - }, - fn: function fn(input: unknown, args: LayerArgs) { - return { - type: 'lens_xy_layer', - ...args, - }; - }, -}; - -export type SeriesType = - | 'bar' - | 'bar_horizontal' - | 'line' - | 'area' - | 'bar_stacked' - | 'bar_percentage_stacked' - | 'bar_horizontal_stacked' - | 'bar_horizontal_percentage_stacked' - | 'area_stacked' - | 'area_percentage_stacked'; - -export type YAxisMode = 'auto' | 'left' | 'right'; - -export type ValueLabelConfig = 'hide' | 'inside' | 'outside'; - -export interface YConfig { - forAccessor: string; - axisMode?: YAxisMode; - color?: string; -} - -export interface XYLayerConfig { - hide?: boolean; - layerId: string; - xAccessor?: string; - accessors: string[]; - yConfig?: YConfig[]; - seriesType: SeriesType; - splitAccessor?: string; - palette?: PaletteOutput; -} - -export interface ValidLayer extends XYLayerConfig { - xAccessor: NonNullable; -} - -export type LayerArgs = XYLayerConfig & { - columnToLabel?: string; // Actually a JSON key-value pair - yScaleType: 'time' | 'linear' | 'log' | 'sqrt'; - xScaleType: 'time' | 'linear' | 'ordinal'; - isHistogram: boolean; - // palette will always be set on the expression - palette: PaletteOutput; -}; - -// Arguments to XY chart expression, with computed properties -export interface XYArgs { - title?: string; - description?: string; - xTitle: string; - yTitle: string; - yRightTitle: string; - yLeftExtent: AxisExtentConfigResult; - yRightExtent: AxisExtentConfigResult; - legend: LegendConfig & { type: 'lens_xy_legendConfig' }; - valueLabels: ValueLabelConfig; - layers: LayerArgs[]; - fittingFunction?: FittingFunction; - axisTitlesVisibilitySettings?: AxesSettingsConfig & { - type: 'lens_xy_axisTitlesVisibilityConfig'; - }; - tickLabelsVisibilitySettings?: AxesSettingsConfig & { type: 'lens_xy_tickLabelsConfig' }; - gridlinesVisibilitySettings?: AxesSettingsConfig & { type: 'lens_xy_gridlinesConfig' }; - curveType?: XYCurveType; - fillOpacity?: number; - hideEndzones?: boolean; - valuesInLegend?: boolean; -} - -export type XYCurveType = 'LINEAR' | 'CURVE_MONOTONE_X'; + XYLayerConfig, + XYCurveType, + AxesSettingsConfig, + FittingFunction, +} from '../../common/expressions'; // Persisted parts of the state export interface XYState { diff --git a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/line_curve_option.tsx b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/line_curve_option.tsx index 1df7744524779b..6080a8c68e57d2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/line_curve_option.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/line_curve_option.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiSwitch } from '@elastic/eui'; -import { XYCurveType } from '../types'; +import type { XYCurveType } from '../../../common/expressions'; export interface LineCurveOptionProps { /** diff --git a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/missing_values_option.tsx b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/missing_values_option.tsx index fb6ecec4d28013..3dba8757903e94 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/missing_values_option.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/missing_values_option.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonGroup, EuiFormRow, EuiIconTip, EuiSuperSelect, EuiText } from '@elastic/eui'; -import { FittingFunction, fittingFunctionDefinitions } from '../fitting_functions'; -import { ValueLabelConfig } from '../types'; +import { fittingFunctionDefinitions } from '../../../common/expressions'; +import type { FittingFunction, ValueLabelConfig } from '../../../common/expressions'; export interface MissingValuesOptionProps { valueLabels?: ValueLabelConfig; diff --git a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.test.tsx b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.test.tsx index ec0c11a0b1d866..b4c8e8f40dde7e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { shallowWithIntl as shallow } from '@kbn/test/jest'; import { Position } from '@elastic/charts'; -import { FramePublicAPI } from '../../types'; +import type { FramePublicAPI } from '../../types'; import { createMockDatasource, createMockFramePublicAPI } from '../../mocks'; import { State } from '../types'; import { VisualOptionsPopover } from './visual_options_popover'; diff --git a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.tsx b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.tsx index 843680e3f28ac6..6d0e5c2d55b704 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visual_options_popover/visual_options_popover.tsx @@ -13,8 +13,8 @@ import { LineCurveOption } from './line_curve_option'; import { FillOpacityOption } from './fill_opacity_option'; import { XYState } from '../types'; import { hasHistogramSeries } from '../state_helpers'; -import { ValidLayer } from '../types'; -import { FramePublicAPI } from '../../types'; +import { ValidLayer } from '../../../common/expressions'; +import type { FramePublicAPI } from '../../types'; function getValueLabelDisableReason({ isAreaPercentage, diff --git a/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts b/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts index 304e323789c147..fd80b9d96d30af 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts @@ -8,7 +8,8 @@ import { getXyVisualization } from './visualization'; import { Position } from '@elastic/charts'; import { Operation } from '../types'; -import { State, SeriesType, XYLayerConfig } from './types'; +import type { State } from './types'; +import type { SeriesType, XYLayerConfig } from '../../common/expressions'; import { createMockDatasource, createMockFramePublicAPI } from '../mocks'; import { LensIconChartBar } from '../assets/chart_bar'; import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks'; diff --git a/x-pack/plugins/lens/public/xy_visualization/visualization.tsx b/x-pack/plugins/lens/public/xy_visualization/visualization.tsx index 199dccdf702f70..40caed7188190a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visualization.tsx @@ -15,14 +15,15 @@ import { PaletteRegistry } from 'src/plugins/charts/public'; import { DataPublicPluginStart } from 'src/plugins/data/public'; import { getSuggestions } from './xy_suggestions'; import { LayerContextMenu, XyToolbar, DimensionEditor } from './xy_config_panel'; -import { +import type { Visualization, OperationMetadata, VisualizationType, AccessorConfig, DatasourcePublicAPI, } from '../types'; -import { State, SeriesType, visualizationTypes, XYLayerConfig, XYState } from './types'; +import { State, visualizationTypes, XYState } from './types'; +import type { SeriesType, XYLayerConfig } from '../../common/expressions'; import { isHorizontalChart } from './state_helpers'; import { toExpression, toPreviewExpression, getSortedAccessors } from './to_expression'; import { LensIconChartBarStacked } from '../assets/chart_bar_stacked'; diff --git a/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx b/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx index 369063644a7545..ccb047d54e3692 100644 --- a/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx @@ -8,8 +8,8 @@ import { uniq } from 'lodash'; import React from 'react'; import { Endzones } from '../../../../../src/plugins/charts/public'; -import { LensMultiTable } from '../types'; -import { LayerArgs } from './types'; +import type { LensMultiTable } from '../../common'; +import type { LayerArgs } from '../../common/expressions'; export interface XDomain { min?: number; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 3128527334553e..061d0cbc4b4b51 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -21,23 +21,21 @@ import { EuiToolTip, EuiIcon, } from '@elastic/eui'; -import { PaletteRegistry } from 'src/plugins/charts/public'; -import { +import type { PaletteRegistry } from 'src/plugins/charts/public'; +import type { VisualizationLayerWidgetProps, VisualizationToolbarProps, VisualizationDimensionEditorProps, - FormatFactory, FramePublicAPI, } from '../types'; -import { - State, +import { State, visualizationTypes, XYState } from './types'; +import type { FormatFactory } from '../../common'; +import type { SeriesType, - visualizationTypes, YAxisMode, AxesSettingsConfig, AxisExtentConfig, - XYState, -} from './types'; +} from '../../common/expressions'; import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers'; import { trackUiEvent } from '../lens_ui_telemetry'; import { LegendSettingsPopover } from '../shared_components'; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts index a494d51f516815..893bd5fd04ee49 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -16,7 +16,8 @@ import { TableSuggestion, TableChangeType, } from '../types'; -import { State, SeriesType, XYState, visualizationTypes, XYLayerConfig } from './types'; +import { State, XYState, visualizationTypes } from './types'; +import type { SeriesType, XYLayerConfig } from '../../common/expressions'; import { getIconForSeries } from './state_helpers'; const columnSortOrder = { diff --git a/x-pack/plugins/lens/server/plugin.tsx b/x-pack/plugins/lens/server/plugin.tsx index c23c98cd12aec9..b47019fa54ec09 100644 --- a/x-pack/plugins/lens/server/plugin.tsx +++ b/x-pack/plugins/lens/server/plugin.tsx @@ -9,6 +9,7 @@ import { Plugin, CoreSetup, CoreStart, PluginInitializerContext, Logger } from ' import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { Observable } from 'rxjs'; import { PluginStart as DataPluginStart } from 'src/plugins/data/server'; +import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import { TaskManagerSetupContract, TaskManagerStartContract } from '../../task_manager/server'; import { setupRoutes } from './routes'; import { @@ -24,6 +25,7 @@ export interface PluginSetupContract { usageCollection?: UsageCollectionSetup; taskManager?: TaskManagerSetupContract; embeddable: EmbeddableSetup; + expressions: ExpressionsServerSetup; } export interface PluginStartContract {