From 50941ebe3566031c540cd46eb8260638442e9f2d Mon Sep 17 00:00:00 2001 From: Diana Derevyankina <54894989+DziyanaDzeraviankina@users.noreply.github.com> Date: Fri, 11 Mar 2022 12:13:19 +0300 Subject: [PATCH] [Lens] Set legend pixel width (#126018) * [Lens] Set legend pixel width * Update tests to include legendSize * Fix typo in legend_settings_popover.test.tsx * Update text for tooltips * Fix row display for small screen * Update legend size setting interface * Fix label condition * Add disable for switch * Change condition for input disabling * Update translation key * Replace legend width setting input with select, make it disabled for horizontal legends and move number of columns setting outside of legend location settings component to place legend width setting above * Capitalize legend sizes select values names Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../expression_functions/heatmap_legend.ts | 6 + .../common/types/expression_functions.ts | 5 + .../public/components/heatmap_component.tsx | 1 + .../mosaic_vis_function.test.ts.snap | 1 + .../pie_vis_function.test.ts.snap | 2 + .../treemap_vis_function.test.ts.snap | 1 + .../waffle_vis_function.test.ts.snap | 1 + .../common/expression_functions/i18n.ts | 4 + .../mosaic_vis_function.ts | 4 + .../expression_functions/pie_vis_function.ts | 4 + .../treemap_vis_function.ts | 4 + .../waffle_vis_function.ts | 4 + .../common/types/expression_renderers.ts | 1 + .../components/partition_vis_component.tsx | 1 + .../vis_types/heatmap/public/to_ast.ts | 1 + src/plugins/vis_types/heatmap/public/types.ts | 1 + .../expressions/xy_chart/legend_config.ts | 11 ++ x-pack/plugins/lens/common/types.ts | 1 + .../toolbar_component.tsx | 10 ++ .../visualization.test.ts | 1 + .../heatmap_visualization/visualization.tsx | 1 + .../public/pie_visualization/to_expression.ts | 1 + .../lens/public/pie_visualization/toolbar.tsx | 7 ++ .../columns_number_setting.test.tsx | 19 +++ .../columns_number_setting.tsx | 84 +++++++++++++ .../legend_location_settings.test.tsx | 13 +- .../legend_location_settings.tsx | 72 +---------- .../legend_settings_popover.test.tsx | 1 + .../legend_settings_popover.tsx | 28 ++++- .../legend_size_settings.tsx | 114 ++++++++++++++++++ .../__snapshots__/to_expression.test.ts.snap | 1 + .../public/xy_visualization/expression.tsx | 1 + .../public/xy_visualization/to_expression.ts | 1 + .../xy_config_panel/index.tsx | 10 ++ 34 files changed, 332 insertions(+), 85 deletions(-) create mode 100644 x-pack/plugins/lens/public/shared_components/columns_number_setting.test.tsx create mode 100644 x-pack/plugins/lens/public/shared_components/columns_number_setting.tsx create mode 100644 x-pack/plugins/lens/public/shared_components/legend_size_settings.tsx diff --git a/src/plugins/chart_expressions/expression_heatmap/common/expression_functions/heatmap_legend.ts b/src/plugins/chart_expressions/expression_heatmap/common/expression_functions/heatmap_legend.ts index 28a37c522ac2d..b5a8d8aa74a2e 100644 --- a/src/plugins/chart_expressions/expression_heatmap/common/expression_functions/heatmap_legend.ts +++ b/src/plugins/chart_expressions/expression_heatmap/common/expression_functions/heatmap_legend.ts @@ -59,6 +59,12 @@ export const heatmapLegendConfig: ExpressionFunctionDefinition< defaultMessage: 'Specifies whether or not the legend items should be truncated.', }), }, + legendSize: { + types: ['number'], + help: i18n.translate('expressionHeatmap.function.args.legendSize.help', { + defaultMessage: 'Specifies the legend size in pixels.', + }), + }, }, fn(input, args) { validateOptions(args.position, Position, errors.invalidPositionError); diff --git a/src/plugins/chart_expressions/expression_heatmap/common/types/expression_functions.ts b/src/plugins/chart_expressions/expression_heatmap/common/types/expression_functions.ts index 10e43e426317d..9208c8b48a29e 100644 --- a/src/plugins/chart_expressions/expression_heatmap/common/types/expression_functions.ts +++ b/src/plugins/chart_expressions/expression_heatmap/common/types/expression_functions.ts @@ -38,6 +38,11 @@ export interface HeatmapLegendConfig { * Defines if the legend items should be truncated */ shouldTruncate?: boolean; + /** + * Exact legend width (vertical) or height (horizontal) + * Limited to max of 70% of the chart container dimension Vertical legends limited to min of 30% of computed width + */ + legendSize?: number; } export type HeatmapLegendConfigResult = HeatmapLegendConfig & { diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx index 76cfc7a50f4ac..7d0e8ad66511d 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx +++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx @@ -481,6 +481,7 @@ export const HeatmapComponent: FC = memo( onElementClick={interactive ? (onElementClick as ElementClickListener) : undefined} showLegend={showLegend ?? args.legend.isVisible} legendPosition={args.legend.position} + legendSize={args.legend.legendSize} legendColorPicker={uiState ? LegendColorPickerWrapper : undefined} debugState={window._echDebugStateFlag ?? false} tooltip={tooltip} diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/mosaic_vis_function.test.ts.snap b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/mosaic_vis_function.test.ts.snap index f1bd7834e52f1..e07e367d10787 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/mosaic_vis_function.test.ts.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/mosaic_vis_function.test.ts.snap @@ -120,6 +120,7 @@ Object { }, "legendDisplay": "show", "legendPosition": "right", + "legendSize": undefined, "maxLegendLines": 2, "metric": Object { "accessor": 0, diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/pie_vis_function.test.ts.snap b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/pie_vis_function.test.ts.snap index d73f53277a2ba..28d5f35c89cbf 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/pie_vis_function.test.ts.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/pie_vis_function.test.ts.snap @@ -112,6 +112,7 @@ Object { }, "legendDisplay": "show", "legendPosition": "right", + "legendSize": undefined, "maxLegendLines": 2, "metric": Object { "accessor": 0, @@ -245,6 +246,7 @@ Object { }, "legendDisplay": "show", "legendPosition": "right", + "legendSize": undefined, "maxLegendLines": 2, "metric": Object { "accessor": 0, diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/treemap_vis_function.test.ts.snap b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/treemap_vis_function.test.ts.snap index b8d8032fa5839..ff2a4ece368f8 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/treemap_vis_function.test.ts.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/treemap_vis_function.test.ts.snap @@ -120,6 +120,7 @@ Object { }, "legendDisplay": "show", "legendPosition": "right", + "legendSize": undefined, "maxLegendLines": 2, "metric": Object { "accessor": 0, diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/waffle_vis_function.test.ts.snap b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/waffle_vis_function.test.ts.snap index 7c6922cdff84a..b0905139d3f1b 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/waffle_vis_function.test.ts.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/__snapshots__/waffle_vis_function.test.ts.snap @@ -102,6 +102,7 @@ Object { }, "legendDisplay": "show", "legendPosition": "right", + "legendSize": undefined, "maxLegendLines": 2, "metric": Object { "accessor": 0, diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/i18n.ts b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/i18n.ts index deedb10940253..7800b81ec91ad 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/i18n.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/i18n.ts @@ -47,6 +47,10 @@ export const strings = { i18n.translate('expressionPartitionVis.reusable.function.args.legendPositionHelpText', { defaultMessage: 'Position the legend on top, bottom, left, right of the chart', }), + getLegendSizeArgHelp: () => + i18n.translate('expressionPartitionVis.reusable.function.args.legendSizeHelpText', { + defaultMessage: 'Specifies the legend size in pixels', + }), getNestedLegendArgHelp: () => i18n.translate('expressionPartitionVis.reusable.function.args.nestedLegendHelpText', { defaultMessage: 'Show a more detailed legend', diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/mosaic_vis_function.ts b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/mosaic_vis_function.ts index 9b80b20d609c0..a0058f38b0f8c 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/mosaic_vis_function.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/mosaic_vis_function.ts @@ -62,6 +62,10 @@ export const mosaicVisFunction = (): MosaicVisExpressionFunctionDefinition => ({ help: strings.getLegendPositionArgHelp(), options: [Position.Top, Position.Right, Position.Bottom, Position.Left], }, + legendSize: { + types: ['number'], + help: strings.getLegendSizeArgHelp(), + }, nestedLegend: { types: ['boolean'], help: strings.getNestedLegendArgHelp(), diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/pie_vis_function.ts b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/pie_vis_function.ts index d42af6c327800..f0dc14d9bf4c7 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/pie_vis_function.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/pie_vis_function.ts @@ -62,6 +62,10 @@ export const pieVisFunction = (): PieVisExpressionFunctionDefinition => ({ help: strings.getLegendPositionArgHelp(), options: [Position.Top, Position.Right, Position.Bottom, Position.Left], }, + legendSize: { + types: ['number'], + help: strings.getLegendSizeArgHelp(), + }, nestedLegend: { types: ['boolean'], help: strings.getNestedLegendArgHelp(), diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/treemap_vis_function.ts b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/treemap_vis_function.ts index 354cc8167839f..1a9a8ac79f631 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/treemap_vis_function.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/treemap_vis_function.ts @@ -62,6 +62,10 @@ export const treemapVisFunction = (): TreemapVisExpressionFunctionDefinition => help: strings.getLegendPositionArgHelp(), options: [Position.Top, Position.Right, Position.Bottom, Position.Left], }, + legendSize: { + types: ['number'], + help: strings.getLegendSizeArgHelp(), + }, nestedLegend: { types: ['boolean'], help: strings.getNestedLegendArgHelp(), diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/waffle_vis_function.ts b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/waffle_vis_function.ts index c99685493d26c..a434da73607e6 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/waffle_vis_function.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/expression_functions/waffle_vis_function.ts @@ -61,6 +61,10 @@ export const waffleVisFunction = (): WaffleVisExpressionFunctionDefinition => ({ help: strings.getLegendPositionArgHelp(), options: [Position.Top, Position.Right, Position.Bottom, Position.Left], }, + legendSize: { + types: ['number'], + help: strings.getLegendSizeArgHelp(), + }, truncateLegend: { types: ['boolean'], help: strings.getTruncateLegendArgHelp(), diff --git a/src/plugins/chart_expressions/expression_partition_vis/common/types/expression_renderers.ts b/src/plugins/chart_expressions/expression_partition_vis/common/types/expression_renderers.ts index f26174fd110f7..c6f29ef90c8e9 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/common/types/expression_renderers.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/common/types/expression_renderers.ts @@ -52,6 +52,7 @@ interface VisCommonParams { legendPosition: Position; truncateLegend: boolean; maxLegendLines: number; + legendSize?: number; ariaLabel?: string; } diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx index 4528bad3e9ab5..2b587c942f199 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx @@ -387,6 +387,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => { showLegend ?? shouldShowLegend(visType, visParams.legendDisplay, bucketColumns) } legendPosition={legendPosition} + legendSize={visParams.legendSize} legendMaxDepth={visParams.nestedLegend ? undefined : 1} legendColorPicker={props.uiState ? LegendColorPickerWrapper : undefined} flatLegend={flatLegend} diff --git a/src/plugins/vis_types/heatmap/public/to_ast.ts b/src/plugins/vis_types/heatmap/public/to_ast.ts index b0bb4b2d6de86..d6dc8a8038591 100644 --- a/src/plugins/vis_types/heatmap/public/to_ast.ts +++ b/src/plugins/vis_types/heatmap/public/to_ast.ts @@ -20,6 +20,7 @@ const prepareLegend = (params: HeatmapVisParams) => { position: params.legendPosition, shouldTruncate: params.truncateLegend ?? true, maxLines: params.maxLegendLines ?? 1, + legendSize: params.legendSize, }); return buildExpression([legend]); diff --git a/src/plugins/vis_types/heatmap/public/types.ts b/src/plugins/vis_types/heatmap/public/types.ts index b02dad8656c83..9806b6de772ae 100644 --- a/src/plugins/vis_types/heatmap/public/types.ts +++ b/src/plugins/vis_types/heatmap/public/types.ts @@ -23,6 +23,7 @@ export interface HeatmapVisParams { legendPosition: Position; truncateLegend?: boolean; maxLegendLines?: number; + legendSize?: number; lastRangeIsRightOpen: boolean; percentageMode: boolean; valueAxes: ValueAxis[]; 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 index fdf8d06b59424..bced4e284aa3c 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/legend_config.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/legend_config.ts @@ -45,6 +45,11 @@ export interface LegendConfig { * Flag whether the legend items are truncated or not */ shouldTruncate?: boolean; + /** + * Exact legend width (vertical) or height (horizontal) + * Limited to max of 70% of the chart container dimension Vertical legends limited to min of 30% of computed width + */ + legendSize?: number; } export type LegendConfigResult = LegendConfig & { type: 'lens_xy_legendConfig' }; @@ -121,6 +126,12 @@ export const legendConfig: ExpressionFunctionDefinition< defaultMessage: 'Specifies whether the legend items will be truncated or not', }), }, + legendSize: { + types: ['number'], + help: i18n.translate('xpack.lens.xyChart.legendSize.help', { + defaultMessage: 'Specifies the legend size in pixels.', + }), + }, }, fn: function fn(input: unknown, args: LegendConfig) { return { diff --git a/x-pack/plugins/lens/common/types.ts b/x-pack/plugins/lens/common/types.ts index ae34331fdfb67..422ada21f0a36 100644 --- a/x-pack/plugins/lens/common/types.ts +++ b/x-pack/plugins/lens/common/types.ts @@ -111,6 +111,7 @@ export interface SharedPieLayerState { percentDecimals?: number; emptySizeRatio?: number; legendMaxLines?: number; + legendSize?: number; truncateLegend?: boolean; } 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 7e2f6db9b30cd..66d1cfcb1e5df 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx @@ -110,6 +110,16 @@ export const HeatmapToolbar = memo( legend: { ...state.legend, shouldTruncate: !current }, }); }} + legendSize={state?.legend.legendSize} + onLegendSizeChange={(legendSize) => { + setState({ + ...state, + legend: { + ...state.legend, + legendSize, + }, + }); + }} /> 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 a3d97cdda00fb..f181167cd8d9c 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/heatmap_visualization/visualization.test.ts @@ -418,6 +418,7 @@ describe('heatmap', () => { arguments: { isVisible: [true], position: [Position.Right], + legendSize: [], }, }, ], diff --git a/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx b/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx index 5eebcc0fd6a94..f8c641e4395ed 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/visualization.tsx @@ -340,6 +340,7 @@ export const getHeatmapVisualization = ({ arguments: { isVisible: [state.legend.isVisible], position: [state.legend.position], + legendSize: state.legend.legendSize ? [state.legend.legendSize] : [], }, }, ], 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 fb143bc058e62..adf35785c373f 100644 --- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts @@ -144,6 +144,7 @@ const generateCommonArguments: GenerateExpressionAstArguments = ( legendDisplay: [attributes.isPreview ? LegendDisplay.HIDE : layer.legendDisplay], legendPosition: [layer.legendPosition || Position.Right], maxLegendLines: [layer.legendMaxLines ?? 1], + legendSize: layer.legendSize ? [layer.legendSize] : [], nestedLegend: [!!layer.nestedLegend], truncateLegend: [ layer.truncateLegend ?? getDefaultVisualValuesForLayer(state, datasourceLayers).truncateText, diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx index f188aa12069d7..2c038b0937999 100644 --- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx @@ -123,6 +123,11 @@ export function PieToolbar(props: VisualizationToolbarProps onStateChange({ legendSize: val }), + [onStateChange] + ); + const onValueInLegendChange = useCallback(() => { onStateChange({ showValuesInLegend: !shouldShowValuesInLegend(layer, state.shape), @@ -251,6 +256,8 @@ export function PieToolbar(props: VisualizationToolbarProps ); diff --git a/x-pack/plugins/lens/public/shared_components/columns_number_setting.test.tsx b/x-pack/plugins/lens/public/shared_components/columns_number_setting.test.tsx new file mode 100644 index 0000000000000..50f2dc2fb93dc --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/columns_number_setting.test.tsx @@ -0,0 +1,19 @@ +/* + * 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 React from 'react'; +import { mountWithIntl as mount } from '@kbn/test-jest-helpers'; +import { ColumnsNumberSetting } from './columns_number_setting'; + +describe('Columns Number Setting', () => { + it('should have default the columns input to 1 when no value is given', () => { + const component = mount(); + expect( + component.find('[data-test-subj="lens-legend-location-columns-input"]').at(0).prop('value') + ).toEqual(1); + }); +}); diff --git a/x-pack/plugins/lens/public/shared_components/columns_number_setting.tsx b/x-pack/plugins/lens/public/shared_components/columns_number_setting.tsx new file mode 100644 index 0000000000000..6a1d1ec6d0306 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/columns_number_setting.tsx @@ -0,0 +1,84 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; +import { useDebouncedValue } from './debounced_value'; +import { TooltipWrapper } from './tooltip_wrapper'; + +export const DEFAULT_FLOATING_COLUMNS = 1; + +interface ColumnsNumberSettingProps { + /** + * Sets the number of columns for legend inside chart + */ + floatingColumns?: number; + /** + * Callback on horizontal alignment option change + */ + onFloatingColumnsChange?: (value: number) => void; + /** + * Flag to disable the location settings + */ + isDisabled: boolean; + /** + * Indicates if legend is located outside + */ + isLegendOutside: boolean; +} + +export const ColumnsNumberSetting = ({ + floatingColumns, + onFloatingColumnsChange = () => {}, + isDisabled, + isLegendOutside, +}: ColumnsNumberSettingProps) => { + const { inputValue, handleInputChange } = useDebouncedValue({ + value: floatingColumns ?? DEFAULT_FLOATING_COLUMNS, + onChange: onFloatingColumnsChange, + }); + + return ( + + + { + handleInputChange(Number(e.target.value)); + }} + step={1} + /> + + + ); +}; diff --git a/x-pack/plugins/lens/public/shared_components/legend_location_settings.test.tsx b/x-pack/plugins/lens/public/shared_components/legend_location_settings.test.tsx index 49a53c1abf66f..f4b5ced490663 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_location_settings.test.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_location_settings.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { Position } from '@elastic/charts'; -import { shallowWithIntl as shallow, mountWithIntl as mount } from '@kbn/test-jest-helpers'; +import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; import { LegendLocationSettings, LegendLocationSettingsProps } from './legend_location_settings'; describe('Legend Location Settings', () => { @@ -104,17 +104,6 @@ describe('Legend Location Settings', () => { expect(newProps.onAlignmentChange).toHaveBeenCalled(); }); - it('should have default the columns input to 1 when no value is given', () => { - const newProps = { - ...props, - location: 'inside', - } as LegendLocationSettingsProps; - const component = mount(); - expect( - component.find('[data-test-subj="lens-legend-location-columns-input"]').at(0).prop('value') - ).toEqual(1); - }); - it('should disable the components when is Disabled is true', () => { const newProps = { ...props, diff --git a/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx b/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx index 6791d5586d327..f3ac54ab00a05 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx @@ -7,9 +7,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiButtonGroup, EuiFieldNumber } from '@elastic/eui'; +import { EuiFormRow, EuiButtonGroup } from '@elastic/eui'; import { VerticalAlignment, HorizontalAlignment, Position } from '@elastic/charts'; -import { useDebouncedValue } from './debounced_value'; import { TooltipWrapper } from './tooltip_wrapper'; export interface LegendLocationSettingsProps { @@ -41,22 +40,12 @@ export interface LegendLocationSettingsProps { * Callback on horizontal alignment option change */ onAlignmentChange?: (id: string) => void; - /** - * Sets the number of columns for legend inside chart - */ - floatingColumns?: number; - /** - * Callback on horizontal alignment option change - */ - onFloatingColumnsChange?: (value: number) => void; /** * Flag to disable the location settings */ isDisabled?: boolean; } -const DEFAULT_FLOATING_COLUMNS = 1; - const toggleButtonsIcons = [ { id: Position.Top, @@ -149,32 +138,6 @@ const locationAlignmentButtonsIcons: Array<{ }, ]; -const FloatingColumnsInput = ({ - value, - setValue, - isDisabled, -}: { - value: number; - setValue: (value: number) => void; - isDisabled: boolean; -}) => { - const { inputValue, handleInputChange } = useDebouncedValue({ value, onChange: setValue }); - return ( - { - handleInputChange(Number(e.target.value)); - }} - step={1} - /> - ); -}; - export const LegendLocationSettings: React.FunctionComponent = ({ location, onLocationChange = () => {}, @@ -183,8 +146,6 @@ export const LegendLocationSettings: React.FunctionComponent {}, - floatingColumns, - onFloatingColumnsChange = () => {}, isDisabled = false, }) => { const alignment = `${verticalAlignment || VerticalAlignment.Top}_${ @@ -294,37 +255,6 @@ export const LegendLocationSettings: React.FunctionComponent - {location && ( - - - - - - )} ); }; diff --git a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.test.tsx b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.test.tsx index 0072a6cd2dcce..e76426515548f 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.test.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.test.tsx @@ -38,6 +38,7 @@ describe('Legend Settings', () => { mode: 'auto', onDisplayChange: jest.fn(), onPositionChange: jest.fn(), + onLegendSizeChange: jest.fn(), }; }); diff --git a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx index 875fd2ab26313..481c38815d43d 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx @@ -17,6 +17,8 @@ import { import { Position, VerticalAlignment, HorizontalAlignment } from '@elastic/charts'; import { ToolbarPopover } from '../shared_components'; import { LegendLocationSettings } from './legend_location_settings'; +import { ColumnsNumberSetting } from './columns_number_setting'; +import { LegendSizeSettings } from './legend_size_settings'; import { ToolbarButtonProps } from '../../../../../src/plugins/kibana_react/public'; import { TooltipWrapper } from './tooltip_wrapper'; import { useDebouncedValue } from './debounced_value'; @@ -118,6 +120,14 @@ export interface LegendSettingsPopoverProps { * Button group position */ groupPosition?: ToolbarButtonProps['groupPosition']; + /** + * Legend size in pixels + */ + legendSize?: number; + /** + * Callback on legend size change + */ + onLegendSizeChange: (size?: number) => void; } const DEFAULT_TRUNCATE_LINES = 1; @@ -177,6 +187,8 @@ export const LegendSettingsPopover: React.FunctionComponent {}, shouldTruncate, onTruncateLegendChange = () => {}, + legendSize, + onLegendSizeChange, }) => { return ( + + {location && ( + + )} void; + isVerticalLegend: boolean; + isDisabled: boolean; +} + +const legendSizeOptions: Array<{ value: LegendSizes; inputDisplay: string }> = [ + { + value: LegendSizes.AUTO, + inputDisplay: i18n.translate('xpack.lens.shared.legendSizeSetting.legendSizeOptions.auto', { + defaultMessage: 'Auto', + }), + }, + { + value: LegendSizes.SMALL, + inputDisplay: i18n.translate('xpack.lens.shared.legendSizeSetting.legendSizeOptions.small', { + defaultMessage: 'Small', + }), + }, + { + value: LegendSizes.MEDIUM, + inputDisplay: i18n.translate('xpack.lens.shared.legendSizeSetting.legendSizeOptions.medium', { + defaultMessage: 'Medium', + }), + }, + { + value: LegendSizes.LARGE, + inputDisplay: i18n.translate('xpack.lens.shared.legendSizeSetting.legendSizeOptions.large', { + defaultMessage: 'Large', + }), + }, + { + value: LegendSizes.EXTRA_LARGE, + inputDisplay: i18n.translate( + 'xpack.lens.shared.legendSizeSetting.legendSizeOptions.extraLarge', + { + defaultMessage: 'Extra large', + } + ), + }, +]; + +export const LegendSizeSettings = ({ + legendSize, + onLegendSizeChange, + isVerticalLegend, + isDisabled, +}: LegendSizeSettingsProps) => { + useEffect(() => { + if (legendSize && !isVerticalLegend) { + onLegendSizeChange(undefined); + } + }, [isVerticalLegend, legendSize, onLegendSizeChange]); + + const onLegendSizeOptionChange = useCallback( + (option) => onLegendSizeChange(Number(option) || undefined), + [onLegendSizeChange] + ); + + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap index a2be6c1f43bdf..5992d0bdb7264 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap @@ -145,6 +145,7 @@ Object { "isVisible": Array [ true, ], + "legendSize": Array [], "maxLines": Array [], "position": Array [ "bottom", diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 5bed5d35bc302..68dc8e26f320c 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -613,6 +613,7 @@ export function XYChart({ : legend.isVisible } legendPosition={legend?.isInside ? legendInsideParams : legend.position} + legendSize={legend.legendSize} theme={{ ...chartTheme, barSeriesStyle: { 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 ec93295d647bf..8a79e05cb466b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -168,6 +168,7 @@ export const buildExpression = ( : [], position: [state.legend.position], isInside: state.legend.isInside ? [state.legend.isInside] : [], + legendSize: state.legend.legendSize ? [state.legend.legendSize] : [], horizontalAlignment: state.legend.horizontalAlignment ? [state.legend.horizontalAlignment] : [], diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx index 240b85a74eb2e..1684d822b5576 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx @@ -394,6 +394,16 @@ export const XyToolbar = memo(function XyToolbar( valuesInLegend: !state.valuesInLegend, }); }} + legendSize={state.legend.legendSize} + onLegendSizeChange={(legendSize) => { + setState({ + ...state, + legend: { + ...state.legend, + legendSize, + }, + }); + }} />