diff --git a/src/platform/plugins/shared/chart_expressions/expression_metric/common/types/expression_renderers.ts b/src/platform/plugins/shared/chart_expressions/expression_metric/common/types/expression_renderers.ts index 798f6c49b0bd8..a3ea23a838466 100644 --- a/src/platform/plugins/shared/chart_expressions/expression_metric/common/types/expression_renderers.ts +++ b/src/platform/plugins/shared/chart_expressions/expression_metric/common/types/expression_renderers.ts @@ -48,7 +48,7 @@ export interface MetricVisParam { secondaryLabelPosition: SecondaryMetricProps['labelPosition']; /** * Determines where the metric color should be applied. - * Only applies when the supporting visualization is a panel. + * Only applies when the background chart is a panel. * - 'background': Applies the color to the metric's background area. * - 'value': Applies the color to the Primary Metric's value. */ diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index 1728f25ca739a..374e88b4bfdfe 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -23291,13 +23291,9 @@ "xpack.lens.metric.progressDirectionLabel": "Balkendiagramm-Ausrichtung", "xpack.lens.metric.secondaryMetric": "Sekundäre Metrik", "xpack.lens.metric.summportingVis.needMaxDimension": "Für Balkenvisualisierungen muss ein Höchstwert festgelegt werden.", - "xpack.lens.metric.supportingVis.label": "Unterstützung der Visualisierung", "xpack.lens.metric.supportingVis.metricHasReducedTimeRange": "Linienvisualisierungen können nicht verwendet werden, wenn ein reduzierter Zeitbereich auf die primäre Metrik angewendet wird.", "xpack.lens.metric.supportingVis.needDefaultTimeField": "Linienvisualisierungen erfordern die Verwendung einer Datenansicht mit einem Standardzeitfeld.", "xpack.lens.metric.supportingVis.secondaryMetricHasReducedTimeRange": "Linienvisualisierungen können nicht verwendet werden, wenn ein reduzierter Zeitbereich auf die sekundäre Metrik angewendet wird.", - "xpack.lens.metric.supportingVis.type": "Typ", - "xpack.lens.metric.supportingVisualization.bar": "Leiste", - "xpack.lens.metric.supportingVisualization.trendline": "Liniendiagramm", "xpack.lens.metric.timeField": "Zeitfeld", "xpack.lens.metric.visualizationDescription": "Präsentieren Sie individuelle Schlüsselkennzahlen oder KPIs.", "xpack.lens.missingTimeRangeParam.longMessage": "Die Eigenschaft timeRange ist für die angegebene Konfiguration erforderlich", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 368cf9fb5b5f7..e318474acdd86 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -23609,13 +23609,9 @@ "xpack.lens.metric.progressDirectionLabel": "Orientation de la barre", "xpack.lens.metric.secondaryMetric": "Indicateur secondaire", "xpack.lens.metric.summportingVis.needMaxDimension": "Les visualisations des barres requièrent la définition d'une valeur maximale.", - "xpack.lens.metric.supportingVis.label": "Visualisation de support", "xpack.lens.metric.supportingVis.metricHasReducedTimeRange": "Les visualisations linéaires ne peuvent pas être utilisées lorsqu'une plage temporelle réduite est appliquée à l'indicateur principal.", "xpack.lens.metric.supportingVis.needDefaultTimeField": "Les visualisations linéaires requièrent l'utilisation d'une vue de données avec un champ temporel par défaut.", "xpack.lens.metric.supportingVis.secondaryMetricHasReducedTimeRange": "Les visualisations linéaires ne peuvent pas être utilisées lorsqu'une plage temporelle réduite est appliquée à l'indicateur secondaire.", - "xpack.lens.metric.supportingVis.type": "Type", - "xpack.lens.metric.supportingVisualization.bar": "Barres", - "xpack.lens.metric.supportingVisualization.trendline": "Ligne", "xpack.lens.metric.timeField": "Champ temporel", "xpack.lens.metric.visualizationDescription": "Présentez les indicateurs clés de performance individuels.", "xpack.lens.missingTimeRangeParam.longMessage": "La propriété timeRange est requise pour cette configuration.", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 9f7d800bf6c3a..049ca5b6a7712 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -23638,13 +23638,9 @@ "xpack.lens.metric.progressDirectionLabel": "棒の向き", "xpack.lens.metric.secondaryMetric": "副メトリック", "xpack.lens.metric.summportingVis.needMaxDimension": "棒グラフの可視化では、最大値を定義する必要があります。", - "xpack.lens.metric.supportingVis.label": "可視化のサポート", "xpack.lens.metric.supportingVis.metricHasReducedTimeRange": "縮小された時間範囲が主メトリックに適用されている場合は、折れ線グラフの可視化を使用できません。", "xpack.lens.metric.supportingVis.needDefaultTimeField": "折れ線グラフの可視化では、データビューとデフォルト時刻フィールドを使用する必要があります。", "xpack.lens.metric.supportingVis.secondaryMetricHasReducedTimeRange": "縮小された時間範囲が副メトリックに適用されている場合は、折れ線グラフの可視化を使用できません。", - "xpack.lens.metric.supportingVis.type": "型", - "xpack.lens.metric.supportingVisualization.bar": "棒", - "xpack.lens.metric.supportingVisualization.trendline": "折れ線", "xpack.lens.metric.timeField": "時間フィールド", "xpack.lens.metric.visualizationDescription": "個別の主要メトリックまたはKPIを提供します。", "xpack.lens.missingTimeRangeParam.longMessage": "指定された構成にはtimeRangeプロパティが必須です", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index e81bc79165764..be92f27293785 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -23626,13 +23626,9 @@ "xpack.lens.metric.progressDirectionLabel": "条形图方向", "xpack.lens.metric.secondaryMetric": "次级指标", "xpack.lens.metric.summportingVis.needMaxDimension": "条形图可视化需要定义一个最大值。", - "xpack.lens.metric.supportingVis.label": "支持可视化", "xpack.lens.metric.supportingVis.metricHasReducedTimeRange": "将缩小的时间范围应用于主要指标时,无法使用折线图可视化。", "xpack.lens.metric.supportingVis.needDefaultTimeField": "折线图可视化需要使用具有默认时间字段的数据视图。", "xpack.lens.metric.supportingVis.secondaryMetricHasReducedTimeRange": "将缩小的时间范围应用于次要指标时,无法使用折线图可视化。", - "xpack.lens.metric.supportingVis.type": "类型", - "xpack.lens.metric.supportingVisualization.bar": "条形图", - "xpack.lens.metric.supportingVisualization.trendline": "折线图", "xpack.lens.metric.timeField": "时间字段", "xpack.lens.metric.visualizationDescription": "展示单个关键指标或 KPI。", "xpack.lens.missingTimeRangeParam.longMessage": "给定配置需要包含 timeRange 属性", diff --git a/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.test.tsx b/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.test.tsx index 19c71dd750d99..895384dfd1d30 100644 --- a/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.test.tsx +++ b/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.test.tsx @@ -938,7 +938,7 @@ describe('dimension editor', () => { ); const supportingVisOptions = { - panel: screen.queryByTitle(/panel/i), + none: screen.queryByTitle(/none/i), // in eui when bar or line become disabled they change from input to button so we have to do this weird check bar: screen.queryByTitle(/bar/i) || screen.queryByRole('button', { name: /bar/i }), trendline: screen.queryByTitle(/line/i) || screen.queryByRole('button', { name: /line/i }), @@ -947,7 +947,7 @@ describe('dimension editor', () => { const clickOnSupportingVis = async (type: SupportingVisType) => { const supportingVis = supportingVisOptions[type]; if (!supportingVis) { - throw new Error(`Supporting visualization ${type} not found`); + throw new Error(`Background chart ${type} not found`); } await userEvent.click(supportingVis); }; @@ -1011,18 +1011,18 @@ describe('dimension editor', () => { expect(container).toBeEmptyDOMElement(); }); - describe('supporting visualizations', () => { + describe('background visualizations', () => { const stateWOTrend = { ...metricAccessorState, trendlineLayerId: undefined, }; describe('reflecting visualization state', () => { - it('when `showBar` is false and maximum value is not defined, option `panel` should be selected', () => { + it('when `showBar` is false and maximum value is not defined, option `none` should be selected', () => { const { supportingVisOptions } = renderAdditionalSectionEditor({ state: { ...stateWOTrend, showBar: false, maxAccessor: undefined }, }); - expect(supportingVisOptions.panel).toHaveAttribute('aria-pressed', 'true'); + expect(supportingVisOptions.none).toHaveAttribute('aria-pressed', 'true'); }); it('when `showBar` is true and maximum value is not defined, bar should be selected', () => { @@ -1123,17 +1123,17 @@ describe('dimension editor', () => { const { clickOnSupportingVis } = renderAdditionalSectionEditor({ state: stateWOTrend, }); - await clickOnSupportingVis('panel'); + await clickOnSupportingVis('none'); expect(mockSetState).toHaveBeenCalledWith({ ...stateWOTrend, showBar: false }); expect(props.removeLayer).not.toHaveBeenCalled(); }); - it('selects panel from trendline', async () => { + it('selects none from trendline', async () => { const { clickOnSupportingVis } = renderAdditionalSectionEditor({ state: metricAccessorState, }); - await clickOnSupportingVis('panel'); + await clickOnSupportingVis('none'); expect(mockSetState).toHaveBeenCalledWith({ ...metricAccessorState, showBar: false }); expect(props.removeLayer).toHaveBeenCalledWith(metricAccessorState.trendlineLayerId); @@ -1141,7 +1141,7 @@ describe('dimension editor', () => { expectCalledBefore(mockSetState, props.removeLayer as jest.Mock); }); - it('selects trendline from panel with apply color to value', async () => { + it('selects trendline from none with apply color to value', async () => { const { clickOnSupportingVis } = renderAdditionalSectionEditor({ state: { ...stateWOTrend, @@ -1154,7 +1154,7 @@ describe('dimension editor', () => { ); }); - it('selects bar from panel with apply color to value', async () => { + it('selects bar from none with apply color to value', async () => { const { clickOnSupportingVis } = renderAdditionalSectionEditor({ state: { ...metricAccessorState, @@ -1197,7 +1197,7 @@ describe('dimension editor', () => { }); describe('`apply color to` controls', () => { - it('should show `apply color to` button group when `Panel` option is selected', async () => { + it('should show `apply color to` button group when `None` option is selected', async () => { const { applyColorToBtnGroup, applyColorToOptions } = renderAdditionalSectionEditor({ state: { ...stateWOTrend, showBar: false, maxAccessor: undefined }, }); @@ -1230,7 +1230,7 @@ describe('dimension editor', () => { expect(mockSetState).toHaveBeenCalledWith({ ...mockState, applyColorTo: 'background' }); }); - it('should show help message when color mode static, supporting visualization is panel, apply color to value', () => { + it('should show help message when color mode static, supporting visualization is none, apply color to value', () => { renderAdditionalSectionEditor({ state: { ...stateWOTrend, @@ -1246,7 +1246,7 @@ describe('dimension editor', () => { ); }); - it('should show help message when color mode dynamic, supporting visualization is panel, apply color to value', () => { + it('should show help message when color mode dynamic, supporting visualization is none, apply color to value', () => { renderAdditionalSectionEditor({ state: { ...stateWOTrend, diff --git a/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.tsx b/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.tsx index 863ed16c0c50e..c56f758757a36 100644 --- a/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.tsx +++ b/x-pack/platform/plugins/shared/lens/public/visualizations/metric/dimension_editor.tsx @@ -13,7 +13,6 @@ import { htmlIdGenerator, EuiColorPicker, EuiSpacer, - EuiText, useEuiTheme, EuiColorPalettePicker, } from '@elastic/eui'; @@ -29,11 +28,11 @@ import { } from '@kbn/coloring'; import { getDataBoundsForPalette } from '@kbn/expression-metric-vis-plugin/public'; import { getColumnByAccessor } from '@kbn/chart-expressions-common'; -import { css } from '@emotion/react'; import { DebouncedInput, IconSelect } from '@kbn/visualization-ui-components'; import { useDebouncedValue } from '@kbn/visualization-utils'; import { KbnPalette, useKbnPalettes } from '@kbn/palettes'; import type { VisualizationDimensionEditorProps } from '@kbn/lens-common'; +import { css } from '@emotion/react'; import { PalettePanelContainer, getAccessorType } from '../../shared_components'; import { defaultNumberPaletteParams, defaultPercentagePaletteParams } from './palette_config'; import { DEFAULT_MAX_COLUMNS, getDefaultColor, showingBar } from './visualization'; @@ -48,7 +47,7 @@ import { legacyMetricStateDefaults, } from './constants'; -export type SupportingVisType = 'panel' | 'bar' | 'trendline'; +export type SupportingVisType = 'none' | 'bar' | 'trendline'; export type ApplyColor = 'background' | 'value'; @@ -678,12 +677,15 @@ function PrimaryMetricEditor({ state, setState, datasource, accessor }: SubProps return null; } - // Show static color control in Primary Metric editor when is not numeric. - // Non-numeric metrics do not support the "Supporting visualization" section const showStaticColorControl = !isMetricNumeric; return ( -
+
{showStaticColorControl ? ( ) : null} @@ -795,12 +797,6 @@ function StaticColorControl({ ); } -/** - * Supporting Visualization Section: - * - * This section allows users to configure the "Supporting Visualization" for the metric visualization. - * Users can choose between different visualization types (Panel, Bar, or Trendline) based on the data and configuration. - */ export function DimensionEditorAdditionalSection({ state, datasource, @@ -814,7 +810,6 @@ export function DimensionEditorAdditionalSection({ isInlineEditing, }: Props) { const euiThemeContext = useEuiTheme(); - const { euiTheme } = euiThemeContext; const { isNumeric: isMetricNumeric } = getAccessorType(datasource, accessor); @@ -925,289 +920,285 @@ export function DimensionEditorAdditionalSection({ const colorMode = state.palette ? 'dynamic' : 'static'; return ( -
- + ( +

{text}

+ ))} > -

- {i18n.translate('xpack.lens.metric.supportingVis.label', { - defaultMessage: 'Supporting visualization', + - + data-test-subj="lnsMetric_supporting_visualization_buttons" + options={[ + { + id: `${buttonIdPrefix}panel`, + label: i18n.translate('xpack.lens.metric.backgroundChartNoneLabel', { + defaultMessage: 'None', + }), + value: 'panel', + 'data-test-subj': 'lnsMetric_background_chart_none', + }, + { + id: `${buttonIdPrefix}trendline`, + label: i18n.translate('xpack.lens.metric.sbackgroundChartLineLabel', { + defaultMessage: 'Line', + }), + isDisabled: !supportsTrendline, + value: 'trendline', + 'data-test-subj': 'lnsMetric_background_chart_line', + }, + { + id: `${buttonIdPrefix}bar`, + label: i18n.translate('xpack.lens.metric.backgroundChartBarLabel', { + defaultMessage: 'Bar', + }), + isDisabled: !state.maxAccessor, + value: 'bar', + 'data-test-subj': 'lnsMetric_background_chart_bar', + }, + ]} + idSelected={`${buttonIdPrefix}${selectedSupportingVisualization}`} + onChange={(_id, value) => { + const supportingVisualizationType = value as SupportingVisType; + if (supportingVisualizationType === supportingVisualization(state)) return; + + setState({ + ...state, + showBar: supportingVisualizationType === 'bar', + applyColorTo: metricStateDefaults.applyColorTo, + }); - <> + if (supportingVisualizationType === 'trendline') { + addLayer('metricTrendline'); + } else if (state.trendlineLayerId) { + removeLayer(state.trendlineLayerId); + } + }} + /> + + {showingBar(state) && ( + + { + const newDirection = id.replace(idPrefix, '') as LayoutDirection; + setState({ + ...state, + progressDirection: newDirection, + }); + }} + /> + + )} + {selectedSupportingVisualization === 'panel' && ( ( -

{text}

- ))} + helpText={ + state.applyColorTo === 'value' && !state.palette ? ( +
+ {i18n.translate( + 'xpack.lens.metric.supportingVis.applyColorTo.staticColorValueHelp', + { + defaultMessage: + 'Color palette has been automatically adjusted for provide the required contrast for text elements.', + } + )} +
+ ) : state.applyColorTo === 'value' && state.palette ? ( +
+ {i18n.translate( + 'xpack.lens.metric.supportingVis.applyColorTo.dynamicColorvalueHelp', + { + defaultMessage: 'Color scales might cause accessibility issues.', + } + )} +
+ ) : undefined + } > { + setState({ + ...state, + applyColorTo: newApplyColorTo, + }); + }} + /> +
+ )} + {isMetricNumeric && ( + + { - const supportingVisualizationType = value as SupportingVisType; - if (supportingVisualizationType === supportingVisualization(state)) return; + idSelected={`${idPrefix}${colorMode}`} + onChange={(_id, newColorMode) => { + if (newColorMode === colorMode) return; setState({ ...state, - showBar: supportingVisualizationType === 'bar', - applyColorTo: metricStateDefaults.applyColorTo, + ...(newColorMode === 'dynamic' + ? { + palette: { + ...activePalette, + params: { + ...activePalette.params, + stops: displayStops, + }, + }, + color: undefined, + } + : { + palette: undefined, + color: undefined, + }), }); - - if (supportingVisualizationType === 'trendline') { - addLayer('metricTrendline'); - } else if (state.trendlineLayerId) { - removeLayer(state.trendlineLayerId); - } }} /> - {showingBar(state) && ( - - { - const newDirection = id.replace(idPrefix, '') as LayoutDirection; - setState({ - ...state, - progressDirection: newDirection, - }); - }} - /> - - )} - {selectedSupportingVisualization === 'panel' && ( - - {i18n.translate( - 'xpack.lens.metric.supportingVis.applyColorTo.staticColorValueHelp', - { - defaultMessage: - 'Color palette has been automatically adjusted for provide the required contrast for text elements.', - } - )} -

- ) : state.applyColorTo === 'value' && state.palette ? ( -
- {i18n.translate( - 'xpack.lens.metric.supportingVis.applyColorTo.dynamicColorvalueHelp', - { - defaultMessage: 'Color scales might cause accessibility issues.', - } - )} -
- ) : undefined + )} + {hasDynamicColoring ? ( + + color)} + siblingRef={panelRef} + isInlineEditing={isInlineEditing} > - { + { setState({ ...state, - applyColorTo: newApplyColorTo, + palette: newPalette, }); }} /> - - )} - - {isMetricNumeric && ( - - { - if (newColorMode === colorMode) return; - - setState({ - ...state, - ...(newColorMode === 'dynamic' - ? { - palette: { - ...activePalette, - params: { - ...activePalette.params, - stops: displayStops, - }, - }, - color: undefined, - } - : { - palette: undefined, - color: undefined, - }), - }); - }} - /> - - )} - {hasDynamicColoring ? ( - - color)} - siblingRef={panelRef} - isInlineEditing={isInlineEditing} - > - { - setState({ - ...state, - palette: newPalette, - }); - }} - /> - - - ) : ( - - )} - + + + ) : ( + + )}
); } diff --git a/x-pack/platform/test/functional/apps/lens/group6/metric.ts b/x-pack/platform/test/functional/apps/lens/group6/metric.ts index 37d61812cdcff..4cbc19dbd12bc 100644 --- a/x-pack/platform/test/functional/apps/lens/group6/metric.ts +++ b/x-pack/platform/test/functional/apps/lens/group6/metric.ts @@ -102,7 +102,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await lens.openDimensionEditor( 'lnsMetric_primaryMetricDimensionPanel > lns-dimensionTrigger' ); - await testSubjects.click('lnsMetric_supporting_visualization_trendline'); + await testSubjects.click('lnsMetric_background_chart_line'); await lens.closeDimensionEditor(); await inspector.open('lnsApp_inspectButton'); @@ -195,7 +195,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'lnsMetric_primaryMetricDimensionPanel > lns-dimensionTrigger' ); - await testSubjects.click('lnsMetric_supporting_visualization_panel'); + await testSubjects.click('lnsMetric_background_chart_none'); await lens.closeDimensionEditor(); await lens.waitForVisualization('mtrVis'); @@ -217,7 +217,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'lnsMetric_primaryMetricDimensionPanel > lns-dimensionTrigger' ); - await testSubjects.click('lnsMetric_supporting_visualization_trendline'); + await testSubjects.click('lnsMetric_background_chart_line'); await lens.waitForVisualization('mtrVis'); @@ -236,7 +236,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'lnsMetric_primaryMetricDimensionPanel > lns-dimensionTrigger' ); - await testSubjects.click('lnsMetric_supporting_visualization_panel'); + await testSubjects.click('lnsMetric_background_chart_none'); await lens.waitForVisualization('mtrVis');