From d29f5ede44bb8475b473cf4b8eae3b482697d033 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 9 Oct 2024 14:29:31 +0200 Subject: [PATCH 01/10] [ES|QL] Keep the preferred chart type --- .../public/services/lens_vis_service.ts | 38 ++++++++++++++++++- .../visualizations/xy/visualization.tsx | 2 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/plugins/unified_histogram/public/services/lens_vis_service.ts b/src/plugins/unified_histogram/public/services/lens_vis_service.ts index eccfd663b2557..f8243795c2d41 100644 --- a/src/plugins/unified_histogram/public/services/lens_vis_service.ts +++ b/src/plugins/unified_histogram/public/services/lens_vis_service.ts @@ -19,6 +19,8 @@ import type { Suggestion, TermsIndexPatternColumn, TypedLensByValueInput, + PieVisualizationState, + XYState, } from '@kbn/lens-plugin/public'; import type { AggregateQuery, TimeRange } from '@kbn/es-query'; import { getAggregateQueryMode, isOfAggregateQueryType } from '@kbn/es-query'; @@ -72,6 +74,19 @@ interface LensVisServiceParams { lensSuggestionsApi: LensSuggestionsApi; } +export enum ChartType { + XY = 'XY', + Bar = 'Bar', + Line = 'Line', + Area = 'Area', + Donut = 'Donut', + Heatmap = 'Heat map', + Treemap = 'Treemap', + Tagcloud = 'Tag cloud', + Waffle = 'Waffle', + Table = 'Table', +} + export class LensVisService { private state$: BehaviorSubject; private services: Services; @@ -248,6 +263,7 @@ export class LensVisService { const histogramSuggestionForESQL = this.getHistogramSuggestionForESQL({ queryParams, breakdownField, + preferredVisAttributes: externalVisContext?.attributes, }); if (histogramSuggestionForESQL) { availableSuggestionsWithType.push({ @@ -456,9 +472,11 @@ export class LensVisService { private getHistogramSuggestionForESQL = ({ queryParams, breakdownField, + preferredVisAttributes, }: { queryParams: QueryParams; breakdownField?: DataViewField; + preferredVisAttributes?: UnifiedHistogramVisContext['attributes']; }): Suggestion | undefined => { const { dataView, query, timeRange, columns } = queryParams; const breakdownColumn = breakdownField?.name @@ -503,7 +521,25 @@ export class LensVisService { if (breakdownColumn) { context.textBasedColumns.push(breakdownColumn); } - const suggestions = this.lensSuggestionsApi(context, dataView, ['lnsDatatable']) ?? []; + let preferredChartType = preferredVisAttributes + ? preferredVisAttributes?.visualizationType + : undefined; + + if (preferredChartType === 'lnsXY') { + preferredChartType = (preferredVisAttributes?.state?.visualization as XYState) + ?.preferredSeriesType; + } + if (preferredChartType === 'lnsPie') { + preferredChartType = (preferredVisAttributes?.state?.visualization as PieVisualizationState) + ?.shape; + } + const suggestions = + this.lensSuggestionsApi( + context, + dataView, + ['lnsDatatable'], + preferredChartType as ChartType + ) ?? []; if (suggestions.length) { const suggestion = suggestions[0]; const suggestionVisualizationState = Object.assign({}, suggestion?.visualizationState); diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index 64a2ad4fc2754..0971b60116b2f 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -263,7 +263,7 @@ export const getXyVisualization = ({ getDescription, switchVisualizationType(seriesType: string, state: State, layerId?: string) { - const dataLayer = state.layers.find((l) => l.layerId === layerId); + const dataLayer = state.layers.find((l) => l.layerId === layerId) ?? state.layers[0]; if (dataLayer && !isDataLayer(dataLayer)) { throw new Error('Cannot switch series type for non-data layer'); } From 56fb6e015f33f59fde1d5c065de622aab17d37b5 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Oct 2024 10:15:11 +0200 Subject: [PATCH 02/10] Move chart type enum to visualization utils --- packages/kbn-visualization-utils/index.ts | 1 + packages/kbn-visualization-utils/src/types.ts | 13 +++++++++++++ .../public/services/lens_vis_service.ts | 14 +------------- .../plugins/lens/public/lens_suggestions_api.ts | 14 +------------- .../public/functions/visualize_esql.tsx | 15 +-------------- 5 files changed, 17 insertions(+), 40 deletions(-) diff --git a/packages/kbn-visualization-utils/index.ts b/packages/kbn-visualization-utils/index.ts index 5d4dfecc0ae29..fa4a2fa1b6f55 100644 --- a/packages/kbn-visualization-utils/index.ts +++ b/packages/kbn-visualization-utils/index.ts @@ -11,3 +11,4 @@ export { getTimeZone } from './src/get_timezone'; export { getLensAttributesFromSuggestion } from './src/get_lens_attributes'; export { TooltipWrapper } from './src/tooltip_wrapper'; export { useDebouncedValue } from './src/debounced_value'; +export { ChartType } from './src/types'; diff --git a/packages/kbn-visualization-utils/src/types.ts b/packages/kbn-visualization-utils/src/types.ts index 0337c3349332b..8931ff289ad51 100644 --- a/packages/kbn-visualization-utils/src/types.ts +++ b/packages/kbn-visualization-utils/src/types.ts @@ -43,3 +43,16 @@ export interface Suggestion { changeType: TableChangeType; keptLayerIds: string[]; } + +export enum ChartType { + XY = 'XY', + Bar = 'Bar', + Line = 'Line', + Area = 'Area', + Donut = 'Donut', + Heatmap = 'Heat map', + Treemap = 'Treemap', + Tagcloud = 'Tag cloud', + Waffle = 'Waffle', + Table = 'Table', +} diff --git a/src/plugins/unified_histogram/public/services/lens_vis_service.ts b/src/plugins/unified_histogram/public/services/lens_vis_service.ts index ff3720d6b2588..e774415c7900d 100644 --- a/src/plugins/unified_histogram/public/services/lens_vis_service.ts +++ b/src/plugins/unified_histogram/public/services/lens_vis_service.ts @@ -30,6 +30,7 @@ import type { AggregateQuery, TimeRange } from '@kbn/es-query'; import { getAggregateQueryMode, isOfAggregateQueryType } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; +import type { ChartType } from '@kbn/visualization-utils'; import { LegendSize } from '@kbn/visualizations-plugin/public'; import { XYConfiguration } from '@kbn/visualizations-plugin/common'; import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common'; @@ -78,19 +79,6 @@ interface LensVisServiceParams { lensSuggestionsApi: LensSuggestionsApi; } -export enum ChartType { - XY = 'XY', - Bar = 'Bar', - Line = 'Line', - Area = 'Area', - Donut = 'Donut', - Heatmap = 'Heat map', - Treemap = 'Treemap', - Tagcloud = 'Tag cloud', - Waffle = 'Waffle', - Table = 'Table', -} - export class LensVisService { private state$: BehaviorSubject; private services: Services; diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.ts b/x-pack/plugins/lens/public/lens_suggestions_api.ts index 3bdadbf337227..8270922b48a63 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.ts @@ -6,23 +6,11 @@ */ import type { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; +import type { ChartType } from '@kbn/visualization-utils'; import { getSuggestions } from './editor_frame_service/editor_frame/suggestion_helpers'; import type { DatasourceMap, VisualizationMap, VisualizeEditorContext } from './types'; import type { DataViewsState } from './state_management'; -export enum ChartType { - XY = 'XY', - Bar = 'Bar', - Line = 'Line', - Area = 'Area', - Donut = 'Donut', - Heatmap = 'Heat map', - Treemap = 'Treemap', - Tagcloud = 'Tag cloud', - Waffle = 'Waffle', - Table = 'Table', -} - interface SuggestionsApiProps { context: VisualizeFieldContext | VisualizeEditorContext; dataView: DataView; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx index e1889c7bc199a..a570d4ba0276a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx @@ -37,7 +37,7 @@ import { VisualizeESQLUserIntention, } from '@kbn/observability-ai-assistant-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; -import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; +import { getLensAttributesFromSuggestion, ChartType } from '@kbn/visualization-utils'; import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import ReactDOM from 'react-dom'; import useAsync from 'react-use/lib/useAsync'; @@ -48,19 +48,6 @@ import type { } from '../../common/functions/visualize_esql'; import { ObservabilityAIAssistantAppPluginStartDependencies } from '../types'; -enum ChartType { - XY = 'XY', - Bar = 'Bar', - Line = 'Line', - Area = 'Area', - Donut = 'Donut', - Heatmap = 'Heat map', - Treemap = 'Treemap', - Tagcloud = 'Tag cloud', - Waffle = 'Waffle', - Table = 'Table', -} - interface VisualizeESQLProps { /** Lens start contract, get the ES|QL charts suggestions api */ lens: LensPublicStart; From a391020731507bc11a0a6380317fbbd9e383ea96 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Oct 2024 10:39:46 +0200 Subject: [PATCH 03/10] Keep preferred type in transformational commands too --- .../public/services/lens_vis_service.ts | 42 +++++++++---------- .../public/utils/get_preferred_chart_type.ts | 24 +++++++++++ 2 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts diff --git a/src/plugins/unified_histogram/public/services/lens_vis_service.ts b/src/plugins/unified_histogram/public/services/lens_vis_service.ts index e774415c7900d..bb54702d1b365 100644 --- a/src/plugins/unified_histogram/public/services/lens_vis_service.ts +++ b/src/plugins/unified_histogram/public/services/lens_vis_service.ts @@ -23,14 +23,11 @@ import type { Suggestion, TermsIndexPatternColumn, TypedLensByValueInput, - PieVisualizationState, - XYState, } from '@kbn/lens-plugin/public'; import type { AggregateQuery, TimeRange } from '@kbn/es-query'; import { getAggregateQueryMode, isOfAggregateQueryType } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; -import type { ChartType } from '@kbn/visualization-utils'; import { LegendSize } from '@kbn/visualizations-plugin/public'; import { XYConfiguration } from '@kbn/visualizations-plugin/common'; import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common'; @@ -50,6 +47,7 @@ import { computeInterval } from '../utils/compute_interval'; import { fieldSupportsBreakdown } from '../utils/field_supports_breakdown'; import { shouldDisplayHistogram } from '../layout/helpers'; import { enrichLensAttributesWithTablesData } from '../utils/lens_vis_from_table'; +import { getPreferredChartType } from '../utils/get_preferred_chart_type'; const UNIFIED_HISTOGRAM_LAYER_ID = 'unifiedHistogram'; @@ -150,7 +148,10 @@ export class LensVisService { externalVisContextStatus: UnifiedHistogramExternalVisContextStatus ) => void; }) => { - const allSuggestions = this.getAllSuggestions({ queryParams }); + const allSuggestions = this.getAllSuggestions({ + queryParams, + preferredVisAttributes: externalVisContext?.attributes, + }); const suggestionState = this.getCurrentSuggestionState({ externalVisContext, @@ -516,25 +517,12 @@ export class LensVisService { if (breakdownColumn) { context.textBasedColumns.push(breakdownColumn); } - let preferredChartType = preferredVisAttributes - ? preferredVisAttributes?.visualizationType + const preferredChartType = preferredVisAttributes + ? getPreferredChartType(preferredVisAttributes) : undefined; - if (preferredChartType === 'lnsXY') { - preferredChartType = (preferredVisAttributes?.state?.visualization as XYState) - ?.preferredSeriesType; - } - if (preferredChartType === 'lnsPie') { - preferredChartType = (preferredVisAttributes?.state?.visualization as PieVisualizationState) - ?.shape; - } const suggestions = - this.lensSuggestionsApi( - context, - dataView, - ['lnsDatatable'], - preferredChartType as ChartType - ) ?? []; + this.lensSuggestionsApi(context, dataView, ['lnsDatatable'], preferredChartType) ?? []; if (suggestions.length) { const suggestion = suggestions[0]; const suggestionVisualizationState = Object.assign({}, suggestion?.visualizationState); @@ -598,9 +586,19 @@ export class LensVisService { ); }; - private getAllSuggestions = ({ queryParams }: { queryParams: QueryParams }): Suggestion[] => { + private getAllSuggestions = ({ + queryParams, + preferredVisAttributes, + }: { + queryParams: QueryParams; + preferredVisAttributes?: UnifiedHistogramVisContext['attributes']; + }): Suggestion[] => { const { dataView, columns, query, isPlainRecord } = queryParams; + const preferredChartType = preferredVisAttributes + ? getPreferredChartType(preferredVisAttributes) + : undefined; + const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', @@ -608,7 +606,7 @@ export class LensVisService { query: query && isOfAggregateQueryType(query) ? query : undefined, }; const allSuggestions = isPlainRecord - ? this.lensSuggestionsApi(context, dataView, ['lnsDatatable']) ?? [] + ? this.lensSuggestionsApi(context, dataView, ['lnsDatatable'], preferredChartType) ?? [] : []; return allSuggestions; diff --git a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts new file mode 100644 index 0000000000000..b3570772e0ae6 --- /dev/null +++ b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts @@ -0,0 +1,24 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ +import type { PieVisualizationState, XYState } from '@kbn/lens-plugin/public'; +import type { ChartType } from '@kbn/visualization-utils'; +import type { UnifiedHistogramVisContext } from '../types'; + +export const getPreferredChartType = (visAttributes: UnifiedHistogramVisContext['attributes']) => { + let preferredChartType = visAttributes ? visAttributes?.visualizationType : undefined; + + if (preferredChartType === 'lnsXY') { + preferredChartType = (visAttributes?.state?.visualization as XYState)?.preferredSeriesType; + } + if (preferredChartType === 'lnsPie') { + preferredChartType = (visAttributes?.state?.visualization as PieVisualizationState)?.shape; + } + + return preferredChartType as ChartType; +}; From 6ba9ae5533a5646a3e43efa6fd8b47d92e613ccc Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Oct 2024 12:41:15 +0200 Subject: [PATCH 04/10] Fix ChartType imports --- x-pack/plugins/lens/public/lens_suggestions_api.test.ts | 3 ++- x-pack/plugins/lens/public/plugin.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.test.ts b/x-pack/plugins/lens/public/lens_suggestions_api.test.ts index 80d2f7a71f6ee..9b5fdacc1aa17 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.test.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.test.ts @@ -6,9 +6,10 @@ */ import type { DataView } from '@kbn/data-views-plugin/public'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; +import { ChartType } from '@kbn/visualization-utils'; import { createMockVisualization, DatasourceMock, createMockDatasource } from './mocks'; import { DatasourceSuggestion } from './types'; -import { suggestionsApi, ChartType } from './lens_suggestions_api'; +import { suggestionsApi } from './lens_suggestions_api'; const generateSuggestion = (state = {}, layerId: string = 'first'): DatasourceSuggestion => ({ state, diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index b2293ea43b109..81d6ecdfa3033 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -62,6 +62,7 @@ import { ContentManagementPublicStart, } from '@kbn/content-management-plugin/public'; import { i18n } from '@kbn/i18n'; +import type { ChartType } from '@kbn/visualization-utils'; import type { ServerlessPluginStart } from '@kbn/serverless/public'; import { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { EditorFrameService as EditorFrameServiceType } from './editor_frame_service'; @@ -137,7 +138,6 @@ import { } from '../common/content_management'; import type { EditLensConfigurationProps } from './app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration'; import { savedObjectToEmbeddableAttributes } from './lens_attribute_service'; -import { ChartType } from './lens_suggestions_api'; export type { SaveProps } from './app_plugin'; From a6e712e631cbf4f34f47fa105526018390d603c7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 22 Oct 2024 10:06:20 +0200 Subject: [PATCH 05/10] Adds a unit test --- .../utils/get_preferred_chart_type.test.ts | 43 +++++++++++++++++++ .../public/utils/get_preferred_chart_type.ts | 6 ++- 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/plugins/unified_histogram/public/utils/get_preferred_chart_type.test.ts diff --git a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.test.ts b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.test.ts new file mode 100644 index 0000000000000..40b2e787d5107 --- /dev/null +++ b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.test.ts @@ -0,0 +1,43 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ +import type { UnifiedHistogramVisContext } from '../types'; +import { getPreferredChartType } from './get_preferred_chart_type'; + +describe('getPreferredChartType', () => { + it('should return the correct type if the viz type is not XY or partition chart', () => { + const attributes = { + visualizationType: 'lnsHeatmap', + } as UnifiedHistogramVisContext['attributes']; + expect(getPreferredChartType(attributes)).toEqual('Heatmap'); + }); + + it('should return the correct type if the viz type is a partition chart', () => { + const attributes = { + visualizationType: 'lnsPie', + state: { + visualization: { + shape: 'donut', + }, + }, + } as UnifiedHistogramVisContext['attributes']; + expect(getPreferredChartType(attributes)).toEqual('donut'); + }); + + it('should return the correct type if the viz type is an XY chart', () => { + const attributes = { + visualizationType: 'lnsXY', + state: { + visualization: { + preferredSeriesType: 'line', + }, + }, + } as UnifiedHistogramVisContext['attributes']; + expect(getPreferredChartType(attributes)).toEqual('line'); + }); +}); diff --git a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts index b3570772e0ae6..b881d6f359124 100644 --- a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts +++ b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts @@ -10,8 +10,10 @@ import type { PieVisualizationState, XYState } from '@kbn/lens-plugin/public'; import type { ChartType } from '@kbn/visualization-utils'; import type { UnifiedHistogramVisContext } from '../types'; +const LENS_PREFIX = 'lns'; + export const getPreferredChartType = (visAttributes: UnifiedHistogramVisContext['attributes']) => { - let preferredChartType = visAttributes ? visAttributes?.visualizationType : undefined; + let preferredChartType = visAttributes?.visualizationType; if (preferredChartType === 'lnsXY') { preferredChartType = (visAttributes?.state?.visualization as XYState)?.preferredSeriesType; @@ -20,5 +22,5 @@ export const getPreferredChartType = (visAttributes: UnifiedHistogramVisContext[ preferredChartType = (visAttributes?.state?.visualization as PieVisualizationState)?.shape; } - return preferredChartType as ChartType; + return preferredChartType.replace(LENS_PREFIX, '') as ChartType; }; From dcba4b30846888f20c86a833a14ab082897d4536 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 22 Oct 2024 14:10:26 +0200 Subject: [PATCH 06/10] Add a function description --- .../public/utils/get_preferred_chart_type.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts index b881d6f359124..5f923a1b84042 100644 --- a/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts +++ b/src/plugins/unified_histogram/public/utils/get_preferred_chart_type.ts @@ -12,6 +12,11 @@ import type { UnifiedHistogramVisContext } from '../types'; const LENS_PREFIX = 'lns'; +/* + * This function is used to get the preferred chart type from the lens visAttributes. + * For XY and Pie visualizations, the preferred chart type is stored in the state. + * So for example, an XY chart can be area, line, stacked_bar, etc. and a Pie chart can be donut, pie, etc. + */ export const getPreferredChartType = (visAttributes: UnifiedHistogramVisContext['attributes']) => { let preferredChartType = visAttributes?.visualizationType; From 8bc63895cfbb8d203bf289d7b9f7f75c83882316 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 23 Oct 2024 11:12:51 +0200 Subject: [PATCH 07/10] Adds a FT --- .../apps/discover/esql/_esql_view.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/functional/apps/discover/esql/_esql_view.ts b/test/functional/apps/discover/esql/_esql_view.ts index 31e89ac42f3ea..7b0504b6c20f3 100644 --- a/test/functional/apps/discover/esql/_esql_view.ts +++ b/test/functional/apps/discover/esql/_esql_view.ts @@ -676,6 +676,42 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { `from logstash-* | sort @timestamp desc | limit 10000 | stats countB = count(bytes) by geo.dest | sort countB | where countB > 0\nAND \`geo.dest\`=="BT"` ); }); + + it('should append a where clause by clicking the table without changing the chart type', async () => { + await discover.selectTextBaseLang(); + const testQuery = `from logstash-* | sort @timestamp desc | limit 10000 | stats countB = count(bytes) by geo.dest | sort countB`; + await monacoEditor.setCodeEditorValue(testQuery); + + await testSubjects.click('querySubmitButton'); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + await unifiedFieldList.waitUntilSidebarHasLoaded(); + + // change the type to line + await testSubjects.click('unifiedHistogramEditFlyoutVisualization'); + await header.waitUntilLoadingHasFinished(); + await testSubjects.click('lnsChartSwitchPopover'); + await testSubjects.click('lnsChartSwitchPopover_line'); + await header.waitUntilLoadingHasFinished(); + await testSubjects.click('applyFlyoutButton'); + + await dataGrid.clickCellFilterForButtonExcludingControlColumns(0, 1); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + await unifiedFieldList.waitUntilSidebarHasLoaded(); + + const editorValue = await monacoEditor.getCodeEditorValue(); + expect(editorValue).to.eql( + `from logstash-* | sort @timestamp desc | limit 10000 | stats countB = count(bytes) by geo.dest | sort countB\n| WHERE \`geo.dest\`=="BT"` + ); + + // check that the type is still line + await testSubjects.click('unifiedHistogramEditFlyoutVisualization'); + await header.waitUntilLoadingHasFinished(); + const chartSwitcher = await testSubjects.find('lnsChartSwitchPopover'); + const type = await chartSwitcher.getVisibleText(); + expect(type).to.be('Line'); + }); }); describe('histogram breakdown', () => { From 484beb7915932de6b5ec68d1b32ef1b63c7e305e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 23 Oct 2024 12:40:37 +0200 Subject: [PATCH 08/10] Fixes lens suggestion --- x-pack/plugins/lens/public/lens_suggestions_api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.ts b/x-pack/plugins/lens/public/lens_suggestions_api.ts index 8270922b48a63..50a5b58f52c6d 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.ts @@ -72,7 +72,9 @@ export const suggestionsApi = ({ // to return line / area instead of a bar chart const chartType = preferredChartType?.toLowerCase(); const XYSuggestion = suggestions.find((sug) => sug.visualizationId === 'lnsXY'); - if (XYSuggestion && chartType && ['area', 'line'].includes(chartType)) { + // console.log(['area', 'line'].some((type) => chartType.includes(type))); + const isAreaOrLine = ['area', 'line'].some((type) => chartType?.includes(type)); + if (XYSuggestion && chartType && isAreaOrLine) { const visualizationState = visualizationMap[ XYSuggestion.visualizationId ]?.switchVisualizationType?.(chartType, XYSuggestion?.visualizationState); From a15c58364ade44cba518c823927b15aa7242532d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 23 Oct 2024 12:41:53 +0200 Subject: [PATCH 09/10] Cleanup --- x-pack/plugins/lens/public/lens_suggestions_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.ts b/x-pack/plugins/lens/public/lens_suggestions_api.ts index 50a5b58f52c6d..5c0c4ed77693b 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.ts @@ -72,7 +72,7 @@ export const suggestionsApi = ({ // to return line / area instead of a bar chart const chartType = preferredChartType?.toLowerCase(); const XYSuggestion = suggestions.find((sug) => sug.visualizationId === 'lnsXY'); - // console.log(['area', 'line'].some((type) => chartType.includes(type))); + // a type can be area, line, area_stacked, area_percentage etc const isAreaOrLine = ['area', 'line'].some((type) => chartType?.includes(type)); if (XYSuggestion && chartType && isAreaOrLine) { const visualizationState = visualizationMap[ From 810bc1915d34c5cf56584ab3cb361f3fe496c087 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 24 Oct 2024 09:44:15 +0200 Subject: [PATCH 10/10] Improves unit test --- .../lens/public/lens_suggestions_api.test.ts | 3 ++ .../lens/public/lens_suggestions_api.ts | 46 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.test.ts b/x-pack/plugins/lens/public/lens_suggestions_api.test.ts index 9b5fdacc1aa17..b4461d6dfb500 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.test.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.test.ts @@ -265,6 +265,9 @@ describe('suggestionsApi', () => { datasourceMap.textBased.getDatasourceSuggestionsForVisualizeField.mockReturnValue([ generateSuggestion(), ]); + datasourceMap.textBased.getDatasourceSuggestionsFromCurrentState.mockReturnValue([ + generateSuggestion(), + ]); const context = { dataViewSpec: { id: 'index1', diff --git a/x-pack/plugins/lens/public/lens_suggestions_api.ts b/x-pack/plugins/lens/public/lens_suggestions_api.ts index 5c0c4ed77693b..b7ce399b33a62 100644 --- a/x-pack/plugins/lens/public/lens_suggestions_api.ts +++ b/x-pack/plugins/lens/public/lens_suggestions_api.ts @@ -67,11 +67,33 @@ export const suggestionsApi = ({ dataViews, }); if (!suggestions.length) return []; + const activeVisualization = suggestions[0]; + if ( + activeVisualization.incomplete || + excludedVisualizations?.includes(activeVisualization.visualizationId) + ) { + return []; + } + // compute the rest suggestions depending on the active one and filter out the lnsLegacyMetric + const newSuggestions = getSuggestions({ + datasourceMap, + datasourceStates: { + textBased: { + isLoading: false, + state: activeVisualization.datasourceState, + }, + }, + visualizationMap, + activeVisualization: visualizationMap[activeVisualization.visualizationId], + visualizationState: activeVisualization.visualizationState, + dataViews, + }).filter((sug) => !sug.hide && sug.visualizationId !== 'lnsLegacyMetric'); + // check if there is an XY chart suggested // if user has requested for a line or area, we want to sligthly change the state // to return line / area instead of a bar chart const chartType = preferredChartType?.toLowerCase(); - const XYSuggestion = suggestions.find((sug) => sug.visualizationId === 'lnsXY'); + const XYSuggestion = newSuggestions.find((s) => s.visualizationId === 'lnsXY'); // a type can be area, line, area_stacked, area_percentage etc const isAreaOrLine = ['area', 'line'].some((type) => chartType?.includes(type)); if (XYSuggestion && chartType && isAreaOrLine) { @@ -95,27 +117,7 @@ export const suggestionsApi = ({ return [suggestionFromModel]; } } - const activeVisualization = suggestions[0]; - if ( - activeVisualization.incomplete || - excludedVisualizations?.includes(activeVisualization.visualizationId) - ) { - return []; - } - // compute the rest suggestions depending on the active one and filter out the lnsLegacyMetric - const newSuggestions = getSuggestions({ - datasourceMap, - datasourceStates: { - textBased: { - isLoading: false, - state: activeVisualization.datasourceState, - }, - }, - visualizationMap, - activeVisualization: visualizationMap[activeVisualization.visualizationId], - visualizationState: activeVisualization.visualizationState, - dataViews, - }).filter((sug) => !sug.hide && sug.visualizationId !== 'lnsLegacyMetric'); + const suggestionsList = [activeVisualization, ...newSuggestions]; // if there is no preference from the user, send everything