Skip to content

Commit

Permalink
[Lens] Pie and donuts should have a size ratio setting (#120101)
Browse files Browse the repository at this point in the history
* [WIP][Lens] Waffle visualization type

Closes:  #107059

* add showExtraLegend for waffle

* add tests

* resolved 1 and 5

* resolved 6

* add sortPredicate for waffle chart type

* [Lens] Pie and donuts should have a size ratio setting

* Add a missed condition

* Fix changing size for smallSlices

* Add donut inner area size setting to pie visualization and update it for lens

* Update test and rename some constants

* Rename the setting

* Move handler to a separate useCallback function

* Update size ratios and add condition for legacy charts

* Fix merge conflict issue

* Change constants order

* Add a couple of tests to check if the setting is displayed

* Update ratio sizes

Co-authored-by: Alexey Antonov <[email protected]>
Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
3 people authored Dec 20, 2021
1 parent eea9cdc commit 2d2d702
Show file tree
Hide file tree
Showing 20 changed files with 221 additions and 11 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions src/plugins/vis_types/pie/public/editor/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import { EMPTY_SIZE_RATIOS } from './constants';
import { LabelPositions, ValueFormats } from '../types';

export const getLabelPositions = [
Expand Down Expand Up @@ -38,3 +39,27 @@ export const getValuesFormats = [
value: ValueFormats.VALUE,
},
];

export const emptySizeRatioOptions = [
{
id: 'emptySizeRatioOption-small',
value: EMPTY_SIZE_RATIOS.SMALL,
label: i18n.translate('visTypePie.emptySizeRatioOptions.small', {
defaultMessage: 'Small',
}),
},
{
id: 'emptySizeRatioOption-medium',
value: EMPTY_SIZE_RATIOS.MEDIUM,
label: i18n.translate('visTypePie.emptySizeRatioOptions.medium', {
defaultMessage: 'Medium',
}),
},
{
id: 'emptySizeRatioOption-large',
value: EMPTY_SIZE_RATIOS.LARGE,
label: i18n.translate('visTypePie.emptySizeRatioOptions.large', {
defaultMessage: 'Large',
}),
},
];
14 changes: 14 additions & 0 deletions src/plugins/vis_types/pie/public/editor/components/pie.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,18 @@ describe('PalettePicker', function () {
expect(findTestSubject(component, 'visTypePieValueDecimals').length).toBe(1);
});
});

it('renders the donut size button group for the elastic charts implementation', async () => {
component = mountWithIntl(<PieOptions {...props} />);
await act(async () => {
expect(findTestSubject(component, 'visTypePieEmptySizeRatioButtonGroup').length).toBe(1);
});
});

it('not renders the donut size button group for the vislib implementation', async () => {
component = mountWithIntl(<PieOptions {...props} showElasticChartsOptions={false} />);
await act(async () => {
expect(findTestSubject(component, 'visTypePieEmptySizeRatioButtonGroup').length).toBe(0);
});
});
});
34 changes: 32 additions & 2 deletions src/plugins/vis_types/pie/public/editor/components/pie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { METRIC_TYPE } from '@kbn/analytics';
import {
EuiPanel,
Expand All @@ -17,6 +17,7 @@ import {
EuiIconTip,
EuiFlexItem,
EuiFlexGroup,
EuiButtonGroup,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
Expand All @@ -33,11 +34,15 @@ import { TruncateLabelsOption } from './truncate_labels';
import { PaletteRegistry } from '../../../../../charts/public';
import { DEFAULT_PERCENT_DECIMALS } from '../../../common';
import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../../types';
import { getLabelPositions, getValuesFormats } from '../collections';
import { emptySizeRatioOptions, getLabelPositions, getValuesFormats } from '../collections';
import { getLegendPositions } from '../positions';

export interface PieOptionsProps extends VisEditorOptionsProps<PieVisParams>, PieTypeProps {}

const emptySizeRatioLabel = i18n.translate('visTypePie.editors.pie.emptySizeRatioLabel', {
defaultMessage: 'Inner area size',
});

function DecimalSlider<ParamName extends string>({
paramName,
value,
Expand Down Expand Up @@ -96,6 +101,14 @@ const PieOptions = (props: PieOptionsProps) => {
fetchPalettes();
}, [props.palettes]);

const handleEmptySizeRatioChange = useCallback(
(sizeId) => {
const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value;
setValue('emptySizeRatio', emptySizeRatio);
},
[setValue]
);

return (
<>
<EuiPanel paddingSize="s">
Expand All @@ -116,6 +129,23 @@ const PieOptions = (props: PieOptionsProps) => {
value={stateParams.isDonut}
setValue={setValue}
/>
{props.showElasticChartsOptions && stateParams.isDonut && (
<EuiFormRow label={emptySizeRatioLabel} fullWidth>
<EuiButtonGroup
isFullWidth
name="emptySizeRatio"
buttonSize="compressed"
legend={emptySizeRatioLabel}
options={emptySizeRatioOptions}
idSelected={
emptySizeRatioOptions.find(({ value }) => value === stateParams.emptySizeRatio)
?.id ?? 'emptySizeRatioOption-small'
}
onChange={handleEmptySizeRatioChange}
data-test-subj="visTypePieEmptySizeRatioButtonGroup"
/>
</EuiFormRow>
)}
<BasicOptions {...props} legendPositions={getLegendPositions} />
{props.showElasticChartsOptions && (
<>
Expand Down
13 changes: 13 additions & 0 deletions src/plugins/vis_types/pie/public/editor/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

export enum EMPTY_SIZE_RATIOS {
SMALL = 0.3,
MEDIUM = 0.54,
LARGE = 0.7,
}
2 changes: 2 additions & 0 deletions src/plugins/vis_types/pie/public/pie_fn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { functionWrapper } from '../../../expressions/common/expression_function
import { createPieVisFn } from './pie_fn';
import { PieVisConfig } from './types';
import { Datatable } from '../../../expressions/common/expression_types/specs';
import { EMPTY_SIZE_RATIOS } from './editor/constants';

describe('interpreter/functions#pie', () => {
const fn = functionWrapper(createPieVisFn());
Expand All @@ -23,6 +24,7 @@ describe('interpreter/functions#pie', () => {
addLegend: true,
legendPosition: 'right',
isDonut: true,
emptySizeRatio: EMPTY_SIZE_RATIOS.SMALL,
nestedLegend: true,
truncateLegend: true,
maxLegendLines: true,
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/vis_types/pie/public/pie_fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({
}),
default: false,
},
emptySizeRatio: {
types: ['number'],
help: i18n.translate('visTypePie.function.args.emptySizeRatioHelpText', {
defaultMessage: 'Defines donut inner empty area size',
}),
},
palette: {
types: ['string'],
help: i18n.translate('visTypePie.function.args.paletteHelpText', {
Expand Down
1 change: 1 addition & 0 deletions src/plugins/vis_types/pie/public/to_ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const toExpressionAst: VisToExpressionAst<PieVisParams> = async (vis, par
maxLegendLines: vis.params.maxLegendLines,
distinctColors: vis.params?.distinctColors,
isDonut: vis.params.isDonut,
emptySizeRatio: vis.params.emptySizeRatio,
palette: vis.params?.palette?.name,
labels: prepareLabels(vis.params.labels),
metric: schemas.metric.map(prepareDimension),
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/vis_types/pie/public/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { SerializedFieldFormat } from '../../../../field_formats/common';
import { ExpressionValueVisDimension } from '../../../../visualizations/public';
import { ExpressionValuePieLabels } from '../expression_functions/pie_labels';
import { PaletteOutput, ChartsPluginSetup } from '../../../../charts/public';
import { EMPTY_SIZE_RATIOS } from '../editor/constants';

export interface Dimension {
accessor: number;
Expand All @@ -38,6 +39,7 @@ interface PieCommonParams {
maxLegendLines: number;
distinctColors: boolean;
isDonut: boolean;
emptySizeRatio?: EMPTY_SIZE_RATIOS;
}

export interface LabelsParams {
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/vis_types/pie/public/utils/get_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const getConfig = (
sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill,
sectorLineWidth: 1.5,
circlePadding: 4,
emptySizeRatio: visParams.isDonut ? 0.3 : 0,
emptySizeRatio: visParams.isDonut ? visParams.emptySizeRatio : 0,
...usingMargin,
};
if (!visParams.labels.show) {
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/vis_types/pie/public/vis_type/pie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { DEFAULT_PERCENT_DECIMALS } from '../../common';
import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../types';
import { toExpressionAst } from '../to_ast';
import { getPieOptions } from '../editor/components';
import { EMPTY_SIZE_RATIOS } from '../editor/constants';

export const getPieVisTypeDefinition = ({
showElasticChartsOptions = false,
Expand All @@ -39,6 +40,7 @@ export const getPieVisTypeDefinition = ({
maxLegendLines: 1,
distinctColors: false,
isDonut: true,
emptySizeRatio: EMPTY_SIZE_RATIOS.SMALL,
palette: {
type: 'palette',
name: 'default',
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export const pie: ExpressionFunctionDefinition<
help: '',
types: ['palette'],
},
emptySizeRatio: {
types: ['number'],
help: '',
},
},
inputTypes: ['lens_multitable'],
fn(data: LensMultiTable, args: PieExpressionArgs) {
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/lens/common/expressions/pie_chart/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface SharedPieLayerState {
showValuesInLegend?: boolean;
nestedLegend?: boolean;
percentDecimals?: number;
emptySizeRatio?: number;
legendMaxLines?: number;
truncateLegend?: boolean;
}
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/lens/public/pie_visualization/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@
*/

export const DEFAULT_PERCENT_DECIMALS = 2;

export enum EMPTY_SIZE_RATIOS {
SMALL = 0.3,
MEDIUM = 0.54,
LARGE = 0.7,
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { LensIconChartPie } from '../assets/chart_pie';
import { LensIconChartTreemap } from '../assets/chart_treemap';
import { LensIconChartMosaic } from '../assets/chart_mosaic';
import { LensIconChartWaffle } from '../assets/chart_waffle';
import { EMPTY_SIZE_RATIOS } from './constants';

import type { SharedPieLayerState } from '../../common/expressions';
import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
Expand All @@ -37,6 +38,11 @@ interface PartitionChartMeta {
value: SharedPieLayerState['numberDisplay'];
inputDisplay: string;
}>;
emptySizeRatioOptions?: Array<{
id: string;
value: EMPTY_SIZE_RATIOS;
label: string;
}>;
};
legend: {
flat?: boolean;
Expand Down Expand Up @@ -110,6 +116,30 @@ const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
},
];

const emptySizeRatioOptions: PartitionChartMeta['toolbarPopover']['emptySizeRatioOptions'] = [
{
id: 'emptySizeRatioOption-small',
value: EMPTY_SIZE_RATIOS.SMALL,
label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.small', {
defaultMessage: 'Small',
}),
},
{
id: 'emptySizeRatioOption-medium',
value: EMPTY_SIZE_RATIOS.MEDIUM,
label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.medium', {
defaultMessage: 'Medium',
}),
},
{
id: 'emptySizeRatioOption-large',
value: EMPTY_SIZE_RATIOS.LARGE,
label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.large', {
defaultMessage: 'Large',
}),
},
];

export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
donut: {
icon: LensIconChartDonut,
Expand All @@ -122,6 +152,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
toolbarPopover: {
categoryOptions,
numberOptions,
emptySizeRatioOptions,
},
legend: {
getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export function PieComponent(
legendPosition,
nestedLegend,
percentDecimals,
emptySizeRatio,
legendMaxLines,
truncateLegend,
hideLabels,
Expand Down Expand Up @@ -229,7 +230,7 @@ export function PieComponent(
config.fillLabel = { textColor: 'rgba(0,0,0,0)' };
}
} else {
config.emptySizeRatio = shape === 'donut' ? 0.3 : 0;
config.emptySizeRatio = shape === 'donut' ? emptySizeRatio : 0;

if (hideLabels || categoryDisplay === 'hide') {
// Force all labels to be linked, then prevent links from showing
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/lens/public/pie_visualization/to_expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
import type { Ast } from '@kbn/interpreter/common';
import type { PaletteRegistry } from 'src/plugins/charts/public';
import type { Operation, DatasourcePublicAPI } from '../types';
import { DEFAULT_PERCENT_DECIMALS } from './constants';
import { DEFAULT_PERCENT_DECIMALS, EMPTY_SIZE_RATIOS } from './constants';
import { shouldShowValuesInLegend } from './render_helpers';

import type { PieVisualizationState } from '../../common/expressions';
import { getDefaultVisualValuesForLayer } from '../shared_components/datasource_default_values';

Expand Down Expand Up @@ -59,6 +58,7 @@ function expressionHelper(
categoryDisplay: [layer.categoryDisplay],
legendDisplay: [layer.legendDisplay],
legendPosition: [layer.legendPosition || 'right'],
emptySizeRatio: [layer.emptySizeRatio ?? EMPTY_SIZE_RATIOS.SMALL],
showValuesInLegend: [shouldShowValuesInLegend(layer, state.shape)],
percentDecimals: [
state.shape === 'waffle'
Expand Down
Loading

0 comments on commit 2d2d702

Please sign in to comment.