From 15185a6482b49c86463837e3eb3c598be6e78a0e Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Mon, 7 Jun 2021 13:56:57 +0200 Subject: [PATCH] [Lens] Value in legend (#101353) --- .../legend_settings_popover.tsx | 35 +++++++++++++++++++ .../__snapshots__/to_expression.test.ts.snap | 3 ++ .../xy_visualization/expression.test.tsx | 31 ++++++++++++++++ .../public/xy_visualization/expression.tsx | 10 +++++- .../public/xy_visualization/to_expression.ts | 1 + .../lens/public/xy_visualization/types.ts | 2 ++ .../xy_visualization/xy_config_panel.tsx | 17 +++++++++ .../public/xy_visualization/xy_suggestions.ts | 1 + 8 files changed, 99 insertions(+), 1 deletion(-) 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 23d4858c26263f..e86a81ba662035 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 @@ -45,6 +45,18 @@ export interface LegendSettingsPopoverProps { * Callback on nested switch status change */ onNestedLegendChange?: (event: EuiSwitchEvent) => void; + /** + * value in legend status + */ + valueInLegend?: boolean; + /** + * Callback on value in legend status change + */ + onValueInLegendChange?: (event: EuiSwitchEvent) => void; + /** + * If true, value in legend switch is rendered + */ + renderValueInLegendSwitch?: boolean; /** * Button group position */ @@ -91,6 +103,9 @@ export const LegendSettingsPopover: React.FunctionComponent {}, + valueInLegend, + onValueInLegendChange = () => {}, + renderValueInLegendSwitch, groupPosition = 'right', }) => { return ( @@ -161,6 +176,26 @@ export const LegendSettingsPopover: React.FunctionComponent )} + {renderValueInLegendSwitch && ( + + + + )} ); }; 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 08b3393fafe482..ac8f089d46487f 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 @@ -157,6 +157,9 @@ Object { "valueLabels": Array [ "hide", ], + "valuesInLegend": Array [ + false, + ], "xTitle": Array [ "", ], 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 3fab88248d4a58..ee1f66063ad1db 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -265,6 +265,7 @@ const createArgsWithLayers = (layers: LayerArgs[] = [sampleLayer]): XYArgs => ({ position: Position.Top, }, valueLabels: 'hide', + valuesInLegend: false, axisTitlesVisibilitySettings: { type: 'lens_xy_axisTitlesVisibilityConfig', x: true, @@ -839,6 +840,36 @@ describe('xy_expression', () => { expect(component.find(Settings).prop('xDomain')).toEqual({ minInterval: 101 }); }); + test('disabled legend extra by default', () => { + const { data, args } = sampleArgs(); + const component = shallow(); + expect(component.find(Settings).at(0).prop('showLegendExtra')).toEqual(false); + }); + + test('ignores legend extra for ordinal chart', () => { + const { data, args } = sampleArgs(); + const component = shallow( + + ); + expect(component.find(Settings).at(0).prop('showLegendExtra')).toEqual(false); + }); + + test('shows legend extra for histogram chart', () => { + const { args } = sampleArgs(); + const component = shallow( + + ); + expect(component.find(Settings).at(0).prop('showLegendExtra')).toEqual(true); + }); + test('it renders bar', () => { const { data, args } = sampleArgs(); const component = shallow( diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 9b203faee3a64c..4cd2b55e8d424d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -209,6 +209,13 @@ export const xyChart: ExpressionFunctionDefinition< 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 { @@ -365,6 +372,7 @@ export function XYChart({ hideEndzones, yLeftExtent, yRightExtent, + valuesInLegend, } = args; const chartTheme = chartsThemeService.useChartsTheme(); const chartBaseTheme = chartsThemeService.useChartsBaseTheme(); @@ -602,7 +610,6 @@ export function XYChart({ : legend.isVisible } legendPosition={legend.position} - showLegendExtra={false} theme={{ ...chartTheme, barSeriesStyle: { @@ -622,6 +629,7 @@ export function XYChart({ xDomain={xDomain} onBrushEnd={renderMode !== 'noInteractivity' ? brushHandler : undefined} onElementClick={renderMode !== 'noInteractivity' ? clickHandler : undefined} + showLegendExtra={isHistogramViz && valuesInLegend} /> { const columnToLabel = getColumnToLabelMap(layer, datasourceLayers[layer.layerId]); diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index 531b034b532425..244898eda91ece 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -466,6 +466,7 @@ export interface XYArgs { curveType?: XYCurveType; fillOpacity?: number; hideEndzones?: boolean; + valuesInLegend?: boolean; } export type XYCurveType = 'LINEAR' | 'CURVE_MONOTONE_X'; @@ -488,6 +489,7 @@ export interface XYState { curveType?: XYCurveType; fillOpacity?: number; hideEndzones?: boolean; + valuesInLegend?: boolean; } export type State = XYState; 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 48f0cacf75938a..b3d1f8f062b730 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 @@ -227,6 +227,15 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp }); }; + const nonOrdinalXAxis = state?.layers.every( + (layer) => + !layer.xAccessor || + getScaleType( + props.frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor), + ScaleType.Linear + ) !== 'ordinal' + ); + // only allow changing endzone visibility if it could show up theoretically (if it's a time viz) const onChangeEndzoneVisiblity = state?.layers.every( (layer) => @@ -323,6 +332,14 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp legend: { ...state.legend, position: id as Position }, }); }} + renderValueInLegendSwitch={nonOrdinalXAxis} + valueInLegend={state?.valuesInLegend} + onValueInLegendChange={() => { + setState({ + ...state, + valuesInLegend: !state.valuesInLegend, + }); + }} /> 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 aff33778258fed..a494d51f516815 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -529,6 +529,7 @@ function buildSuggestion({ yTitle: currentState?.yTitle, yRightTitle: currentState?.yRightTitle, hideEndzones: currentState?.hideEndzones, + valuesInLegend: currentState?.valuesInLegend, yLeftExtent: currentState?.yLeftExtent, yRightExtent: currentState?.yRightExtent, axisTitlesVisibilitySettings: currentState?.axisTitlesVisibilitySettings || {