From db3563f4c0276a73b83c3627a09bb43eeff9948b Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 12 May 2020 14:02:36 +0200 Subject: [PATCH 1/2] [Lens] fix empty state for pie --- .../pie_visualization/register_expression.tsx | 17 +++++---- .../pie_visualization/render_function.tsx | 35 ++++++++++--------- .../shared_components/empty_placeholder.tsx | 24 +++++++++++++ .../lens/public/shared_components/index.ts | 7 ++++ .../public/xy_visualization/xy_expression.tsx | 17 ++------- 5 files changed, 63 insertions(+), 37 deletions(-) create mode 100644 x-pack/plugins/lens/public/shared_components/empty_placeholder.tsx create mode 100644 x-pack/plugins/lens/public/shared_components/index.ts diff --git a/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx b/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx index 998d2162f7f5d0..7babf7ed7ff465 100644 --- a/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx @@ -7,6 +7,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { i18n } from '@kbn/i18n'; +import { I18nProvider } from '@kbn/i18n/react'; import { PartialTheme } from '@elastic/charts'; import { IInterpreterRenderHandlers, @@ -111,13 +112,15 @@ export const getPieRenderer = (dependencies: { const executeTriggerActions = getExecuteTriggerActions(); const formatFactory = await dependencies.formatFactory; ReactDOM.render( - , + + + , domNode, () => { handlers.done(); 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 0c27a3e4b44e31..56019b3e6c8912 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -31,6 +31,7 @@ import { CHART_NAMES, DEFAULT_PERCENT_DECIMALS } from './constants'; import { ColumnGroups, PieExpressionProps } from './types'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; import { getSliceValueWithFallback, getFilterContext } from './render_helpers'; +import { EmptyPlaceholder } from '../shared_components'; import './visualization.scss'; const EMPTY_SLICE = Symbol('empty_slice'); @@ -201,27 +202,29 @@ export function PieComponent( const value = row[metricColumn.id]; return typeof value === 'number' && value < 0; }); - if (firstTable.rows.length === 0 || hasNegative) { + const isEmpty = + firstTable.rows.length === 0 || + firstTable.rows.every(row => + groups.every(colId => !row[colId] || typeof row[colId] === 'undefined') + ); + + if (isEmpty) { + return ; + } + + if (hasNegative) { return ( - {hasNegative ? ( - - ) : ( - - )} + ); } - return ( diff --git a/x-pack/plugins/lens/public/shared_components/empty_placeholder.tsx b/x-pack/plugins/lens/public/shared_components/empty_placeholder.tsx new file mode 100644 index 00000000000000..a2ea5c10de1300 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/empty_placeholder.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +export const EmptyPlaceholder = (props: { icon: IconType }) => ( + <> + + + +

+ +

+
+ +); diff --git a/x-pack/plugins/lens/public/shared_components/index.ts b/x-pack/plugins/lens/public/shared_components/index.ts new file mode 100644 index 00000000000000..ad662fd7a59d92 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './empty_placeholder'; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index ab0af94cbc2b4e..a4326360253531 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -26,8 +26,7 @@ import { ExpressionFunctionDefinition, ExpressionValueSearchContext, } from 'src/plugins/expressions/public'; -import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { IconType } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ValueClickTriggerContext, @@ -41,6 +40,7 @@ import { isHorizontalChart } from './state_helpers'; import { getExecuteTriggerActions } from '../services'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; import { parseInterval } from '../../../../../src/plugins/data/common'; +import { EmptyPlaceholder } from '../shared_components'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -193,18 +193,7 @@ export function XYChart({ if (filteredLayers.length === 0) { const icon: IconType = layers.length > 0 ? getIconForSeriesType(layers[0].seriesType) : 'bar'; - return ( - - - -

- -

-
- ); + return ; } // use formatting hint of first x axis column to format ticks From a611ae9cbdb8d3111420a73e01812b8932ac9d51 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 13 May 2020 10:34:04 +0200 Subject: [PATCH 2/2] test added --- .../render_function.test.tsx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 bdc8004540bae9..b0d4e0d2cc52b6 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 @@ -10,6 +10,7 @@ import { shallow } from 'enzyme'; import { LensMultiTable } from '../types'; import { PieComponent } from './render_function'; import { PieExpressionArgs } from './types'; +import { EmptyPlaceholder } from '../shared_components'; describe('PieVisualization component', () => { let getFormatSpy: jest.Mock; @@ -109,5 +110,26 @@ describe('PieVisualization component', () => { ); expect(component.find(Settings).prop('legendMaxDepth')).toBeUndefined(); }); + + test('it shows emptyPlaceholder for undefined grouped data', () => { + const defaultData = getDefaultArgs().data; + const emptyData: LensMultiTable = { + ...defaultData, + tables: { + first: { + ...defaultData.tables.first, + rows: [ + { a: undefined, b: undefined, c: 'I', d: 'Row 1' }, + { a: undefined, b: undefined, c: 'J', d: 'Row 2' }, + ], + }, + }, + }; + + const component = shallow( + + ); + expect(component.find(EmptyPlaceholder).prop('icon')).toEqual('visPie'); + }); }); });