From a5c67a7aa8054e8cecd431ee21d38044c6a0dbc5 Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Mon, 22 Nov 2021 18:21:29 +0300
Subject: [PATCH 01/18] [WIP][Lens] Waffle visualization type

Closes:  #107059
---
 .../common/expressions/pie_chart/types.ts     |   2 +-
 .../lens/public/assets/chart_waffle.tsx       |  31 ++++
 .../public/pie_visualization/constants.ts     |  97 -----------
 .../partition_charts_meta.ts                  | 161 ++++++++++++++++++
 .../pie_visualization/render_function.tsx     |   8 +-
 .../pie_visualization/render_helpers.ts       |  14 +-
 .../pie_visualization/suggestions.test.ts     |   4 +-
 .../public/pie_visualization/suggestions.ts   |  99 +++++++++--
 .../lens/public/pie_visualization/toolbar.tsx |  80 ++++-----
 .../pie_visualization/visualization.tsx       | 113 ++++++------
 10 files changed, 385 insertions(+), 224 deletions(-)
 create mode 100644 x-pack/plugins/lens/public/assets/chart_waffle.tsx
 create mode 100644 x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts

diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
index 00fc7abaa043b..8c9ec4e5a54e7 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
@@ -8,7 +8,7 @@
 import type { PaletteOutput } from '../../../../../../src/plugins/charts/common';
 import type { LensMultiTable, LayerType } from '../../types';
 
-export type PieChartTypes = 'donut' | 'pie' | 'treemap' | 'mosaic';
+export type PieChartTypes = 'donut' | 'pie' | 'treemap' | 'mosaic' | 'waffle';
 
 export interface SharedPieLayerState {
   groups: string[];
diff --git a/x-pack/plugins/lens/public/assets/chart_waffle.tsx b/x-pack/plugins/lens/public/assets/chart_waffle.tsx
new file mode 100644
index 0000000000000..b9ee0557faea9
--- /dev/null
+++ b/x-pack/plugins/lens/public/assets/chart_waffle.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 type { EuiIconProps } from '@elastic/eui';
+
+export const LensIconChartWaffle = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
+  <svg
+    viewBox="0 0 30 22"
+    width={30}
+    height={22}
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    aria-labelledby={titleId}
+    {...props}
+  >
+    {title ? <title id={titleId} /> : null}
+    <path
+      className="lensChartIcon__accent"
+      d="M16 1a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V1zM4 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM17 6a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V7a1 1 0 00-1-1h-2zM23 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM5 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1H5zM4 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V7zM11 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM10 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7zM11 12a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM22 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7z"
+    />
+    <path
+      className="lensChartIcon__subdued"
+      d="M22 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM4 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM16 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM11 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM23 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM16 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2z"
+    />
+  </svg>
+);
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index be0afc65aed3b..bfb263b415891 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -5,101 +5,4 @@
  * 2.0.
  */
 
-import { i18n } from '@kbn/i18n';
-import { PartitionLayout } from '@elastic/charts';
-import { LensIconChartDonut } from '../assets/chart_donut';
-import { LensIconChartPie } from '../assets/chart_pie';
-import { LensIconChartTreemap } from '../assets/chart_treemap';
-import { LensIconChartMosaic } from '../assets/chart_mosaic';
-
-import type { SharedPieLayerState } from '../../common/expressions';
-
-interface CategoryOption {
-  value: SharedPieLayerState['categoryDisplay'];
-  inputDisplay: string;
-}
-
-const groupLabel = i18n.translate('xpack.lens.pie.groupLabel', {
-  defaultMessage: 'Proportion',
-});
-
-const categoryOptions: CategoryOption[] = [
-  {
-    value: 'default',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.showCategoriesLabel', {
-      defaultMessage: 'Inside or outside',
-    }),
-  },
-  {
-    value: 'inside',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.fitInsideOnlyLabel', {
-      defaultMessage: 'Inside only',
-    }),
-  },
-  {
-    value: 'hide',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.categoriesInLegendLabel', {
-      defaultMessage: 'Hide labels',
-    }),
-  },
-];
-
-const categoryOptionsTreemap: CategoryOption[] = [
-  {
-    value: 'default',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.showTreemapCategoriesLabel', {
-      defaultMessage: 'Show labels',
-    }),
-  },
-  {
-    value: 'hide',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.categoriesInLegendLabel', {
-      defaultMessage: 'Hide labels',
-    }),
-  },
-];
-
-export const CHART_NAMES = {
-  donut: {
-    icon: LensIconChartDonut,
-    label: i18n.translate('xpack.lens.pie.donutLabel', {
-      defaultMessage: 'Donut',
-    }),
-    partitionType: PartitionLayout.sunburst,
-    groupLabel,
-    categoryOptions,
-  },
-  pie: {
-    icon: LensIconChartPie,
-    label: i18n.translate('xpack.lens.pie.pielabel', {
-      defaultMessage: 'Pie',
-    }),
-    partitionType: PartitionLayout.sunburst,
-    groupLabel,
-    categoryOptions,
-  },
-  treemap: {
-    icon: LensIconChartTreemap,
-    label: i18n.translate('xpack.lens.pie.treemaplabel', {
-      defaultMessage: 'Treemap',
-    }),
-    partitionType: PartitionLayout.treemap,
-    groupLabel,
-    categoryOptions: categoryOptionsTreemap,
-  },
-  mosaic: {
-    icon: LensIconChartMosaic,
-    label: i18n.translate('xpack.lens.pie.mosaiclabel', {
-      defaultMessage: 'Mosaic',
-    }),
-    partitionType: PartitionLayout.mosaic,
-    groupLabel,
-    categoryOptions: [] as CategoryOption[],
-  },
-};
-
-export const MAX_PIE_BUCKETS = 3;
-export const MAX_TREEMAP_BUCKETS = 2;
-export const MAX_MOSAIC_BUCKETS = 2;
-
 export const DEFAULT_PERCENT_DECIMALS = 2;
diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
new file mode 100644
index 0000000000000..b88a457cc8f9e
--- /dev/null
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -0,0 +1,161 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import { PartitionLayout } from '@elastic/charts';
+import type { EuiIconProps } from '@elastic/eui';
+
+import { LensIconChartDonut } from '../assets/chart_donut';
+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 type { SharedPieLayerState } from '../../common/expressions';
+import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
+
+interface PartitionChartMeta {
+  icon: ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => JSX.Element;
+  label: string;
+  partitionType: PartitionLayout;
+  groupLabel: string;
+  categoryOptions: Array<{
+    value: SharedPieLayerState['categoryDisplay'];
+    inputDisplay: string;
+  }>;
+  numberOptions: Array<{
+    value: SharedPieLayerState['numberDisplay'];
+    inputDisplay: string;
+  }>;
+  maxBuckets: number;
+  isExperimental?: boolean;
+  requiredMinDimensionCount?: number;
+  flatLegend?: boolean;
+}
+
+const groupLabel = i18n.translate('xpack.lens.pie.groupLabel', {
+  defaultMessage: 'Proportion',
+});
+
+const categoryOptions: PartitionChartMeta['categoryOptions'] = [
+  {
+    value: 'default',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.showCategoriesLabel', {
+      defaultMessage: 'Inside or outside',
+    }),
+  },
+  {
+    value: 'inside',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.fitInsideOnlyLabel', {
+      defaultMessage: 'Inside only',
+    }),
+  },
+  {
+    value: 'hide',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.categoriesInLegendLabel', {
+      defaultMessage: 'Hide labels',
+    }),
+  },
+];
+
+const categoryOptionsTreemap: PartitionChartMeta['categoryOptions'] = [
+  {
+    value: 'default',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.showTreemapCategoriesLabel', {
+      defaultMessage: 'Show labels',
+    }),
+  },
+  {
+    value: 'hide',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.categoriesInLegendLabel', {
+      defaultMessage: 'Hide labels',
+    }),
+  },
+];
+
+const numberOptions: PartitionChartMeta['numberOptions'] = [
+  {
+    value: 'hidden',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.hiddenNumbersLabel', {
+      defaultMessage: 'Hide from chart',
+    }),
+  },
+  {
+    value: 'percent',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.showPercentValuesLabel', {
+      defaultMessage: 'Show percent',
+    }),
+  },
+  {
+    value: 'value',
+    inputDisplay: i18n.translate('xpack.lens.pieChart.showFormatterValuesLabel', {
+      defaultMessage: 'Show value',
+    }),
+  },
+];
+
+export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
+  donut: {
+    icon: LensIconChartDonut,
+    label: i18n.translate('xpack.lens.pie.donutLabel', {
+      defaultMessage: 'Donut',
+    }),
+    partitionType: PartitionLayout.sunburst,
+    groupLabel,
+    categoryOptions,
+    numberOptions,
+    maxBuckets: 3,
+  },
+  pie: {
+    icon: LensIconChartPie,
+    label: i18n.translate('xpack.lens.pie.pielabel', {
+      defaultMessage: 'Pie',
+    }),
+    partitionType: PartitionLayout.sunburst,
+    groupLabel,
+    categoryOptions,
+    numberOptions,
+    maxBuckets: 3,
+  },
+  treemap: {
+    icon: LensIconChartTreemap,
+    label: i18n.translate('xpack.lens.pie.treemaplabel', {
+      defaultMessage: 'Treemap',
+    }),
+    partitionType: PartitionLayout.treemap,
+    groupLabel,
+    categoryOptions: categoryOptionsTreemap,
+    numberOptions,
+    maxBuckets: 2,
+  },
+  mosaic: {
+    icon: LensIconChartMosaic,
+    label: i18n.translate('xpack.lens.pie.mosaiclabel', {
+      defaultMessage: 'Mosaic',
+    }),
+    partitionType: PartitionLayout.mosaic,
+    groupLabel,
+    categoryOptions: [],
+    numberOptions,
+    maxBuckets: 2,
+    isExperimental: true,
+    requiredMinDimensionCount: 2,
+  },
+  waffle: {
+    icon: LensIconChartWaffle,
+    label: i18n.translate('xpack.lens.pie.wafflelabel', {
+      defaultMessage: 'Waffle',
+    }),
+    partitionType: PartitionLayout.waffle,
+    groupLabel,
+    categoryOptions: [],
+    numberOptions: [],
+    maxBuckets: 1,
+    isExperimental: true,
+    flatLegend: true,
+  },
+};
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 2bf9827bb976e..f2faed801b797 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -25,7 +25,8 @@ import {
 import { RenderMode } from 'src/plugins/expressions';
 import type { LensFilterEvent } from '../types';
 import { VisualizationContainer } from '../visualization_container';
-import { CHART_NAMES, DEFAULT_PERCENT_DECIMALS } from './constants';
+import { DEFAULT_PERCENT_DECIMALS } from './constants';
+import { PartitionChartsMeta } from './partition_charts_meta';
 import type { FormatFactory } from '../../common';
 import type { PieExpressionProps } from '../../common/expressions';
 import {
@@ -210,7 +211,7 @@ export function PieComponent(
   });
 
   const config: RecursivePartial<PartitionConfig> = {
-    partitionLayout: CHART_NAMES[shape].partitionType,
+    partitionLayout: PartitionChartsMeta[shape].partitionType,
     fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily,
     outerSizeRatio: 1,
     specialFirstInnermostSector: true,
@@ -292,7 +293,7 @@ export function PieComponent(
           id="xpack.lens.pie.pieWithNegativeWarningLabel"
           defaultMessage="{chartType} charts can't render with negative values."
           values={{
-            chartType: CHART_NAMES[shape].label,
+            chartType: PartitionChartsMeta[shape].label,
           }}
         />
       </EuiText>
@@ -322,6 +323,7 @@ export function PieComponent(
                 bucketColumns.length > 1 &&
                 !isTreemapOrMosaicShape(shape)))
           }
+          flatLegend={PartitionChartsMeta[shape].flatLegend}
           legendPosition={legendPosition || Position.Right}
           legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */}
           onElementClick={props.interactive ?? true ? onElementClickHandler : undefined}
diff --git a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts
index bdffacde65639..fa20eb6f20fa8 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts
@@ -39,7 +39,7 @@ export function getFilterContext(
 }
 
 export const isPartitionShape = (shape: PieChartTypes | string) =>
-  ['donut', 'pie', 'treemap', 'mosaic'].includes(shape);
+  ['donut', 'pie', 'treemap', 'mosaic', 'waffle'].includes(shape);
 
 export const isTreemapOrMosaicShape = (shape: PieChartTypes | string) =>
   ['treemap', 'mosaic'].includes(shape);
@@ -95,3 +95,15 @@ export const byDataColorPaletteMap = (
     },
   };
 };
+
+export const checkTableForContainsSmallValues = (
+  dataTable: Datatable,
+  columnId: string,
+  minPercentage: number
+) => {
+  const overallSum = dataTable.rows.reduce(
+    (partialSum, row) => Number(row[columnId]) + partialSum,
+    0
+  );
+  return dataTable.rows.some((row) => (row[columnId] / overallSum) * 100 < minPercentage);
+};
diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
index 656d00960766e..30e5c22d2af5e 100644
--- a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
@@ -304,7 +304,7 @@ describe('suggestions', () => {
         state: undefined,
         keptLayerIds: ['first'],
       });
-      expect(currentSuggestions).toHaveLength(4);
+      expect(currentSuggestions).toHaveLength(5);
       expect(currentSuggestions.every((s) => s.hide)).toEqual(true);
     });
 
@@ -324,7 +324,7 @@ describe('suggestions', () => {
         state: undefined,
         keptLayerIds: ['first'],
       });
-      expect(currentSuggestions).toHaveLength(4);
+      expect(currentSuggestions).toHaveLength(5);
       expect(currentSuggestions.every((s) => s.hide)).toEqual(true);
     });
 
diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
index 30cd63752f420..c0adf7befa1fc 100644
--- a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
@@ -10,8 +10,9 @@ import { i18n } from '@kbn/i18n';
 import type { SuggestionRequest, TableSuggestionColumn, VisualizationSuggestion } from '../types';
 import { layerTypes } from '../../common';
 import type { PieVisualizationState } from '../../common/expressions';
-import { CHART_NAMES, MAX_MOSAIC_BUCKETS, MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS } from './constants';
-import { isPartitionShape, isTreemapOrMosaicShape } from './render_helpers';
+import { PartitionChartsMeta } from './partition_charts_meta';
+import { isPartitionShape } from './render_helpers';
+import { PieChartTypes } from '../../common/expressions/pie_chart/types';
 
 function hasIntervalScale(columns: TableSuggestionColumn[]) {
   return columns.some((col) => col.operation.scale === 'interval');
@@ -30,6 +31,27 @@ function shouldReject({ table, keptLayerIds, state }: SuggestionRequest<PieVisua
   );
 }
 
+function getNewShape(
+  groups: TableSuggestionColumn[],
+  subVisualizationId?: PieVisualizationState['shape']
+) {
+  if (subVisualizationId) {
+    return subVisualizationId;
+  }
+
+  let newShape: PieVisualizationState['shape'] | undefined;
+
+  if (groups.length !== 1 && !subVisualizationId) {
+    newShape = 'pie';
+  }
+
+  return newShape ?? 'donut';
+}
+
+function hasCustomSuggestionsExists(shape: PieChartTypes | string | undefined) {
+  return shape ? ['treemap', 'waffle', 'mosaic'].includes(shape) : false;
+}
+
 export function suggestions({
   table,
   state,
@@ -45,7 +67,11 @@ export function suggestions({
 
   const [groups, metrics] = partition(table.columns, (col) => col.operation.isBucketed);
 
-  if (metrics.length > 1 || groups.length > Math.max(MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS)) {
+  if (
+    metrics.length > 1 ||
+    groups.length >
+      Math.max(...Object.values(PartitionChartsMeta).map(({ maxBuckets }) => maxBuckets))
+  ) {
     return [];
   }
 
@@ -61,20 +87,18 @@ export function suggestions({
 
   const results: Array<VisualizationSuggestion<PieVisualizationState>> = [];
 
-  if (groups.length <= MAX_PIE_BUCKETS && !isTreemapOrMosaicShape(subVisualizationId!)) {
-    let newShape: PieVisualizationState['shape'] =
-      (subVisualizationId as PieVisualizationState['shape']) || 'donut';
-    if (groups.length !== 1 && !subVisualizationId) {
-      newShape = 'pie';
-    }
-
+  if (
+    groups.length <= PartitionChartsMeta.pie.maxBuckets &&
+    !hasCustomSuggestionsExists(subVisualizationId)
+  ) {
+    const newShape = getNewShape(groups, subVisualizationId as PieVisualizationState['shape']);
     const baseSuggestion: VisualizationSuggestion<PieVisualizationState> = {
       title: i18n.translate('xpack.lens.pie.suggestionLabel', {
         defaultMessage: 'As {chartName}',
-        values: { chartName: CHART_NAMES[newShape].label },
+        values: { chartName: PartitionChartsMeta[newShape].label },
         description: 'chartName is already translated',
       }),
-      score: state && !isTreemapOrMosaicShape(state.shape) ? 0.6 : 0.4,
+      score: state && !hasCustomSuggestionsExists(state.shape) ? 0.6 : 0.4,
       state: {
         shape: newShape,
         palette: mainPalette || state?.palette,
@@ -104,7 +128,7 @@ export function suggestions({
       hide:
         table.changeType === 'reduced' ||
         hasIntervalScale(groups) ||
-        (state && !isTreemapOrMosaicShape(state.shape)),
+        (state && !hasCustomSuggestionsExists(state.shape)),
     };
 
     results.push(baseSuggestion);
@@ -112,7 +136,7 @@ export function suggestions({
       ...baseSuggestion,
       title: i18n.translate('xpack.lens.pie.suggestionLabel', {
         defaultMessage: 'As {chartName}',
-        values: { chartName: CHART_NAMES[newShape === 'pie' ? 'donut' : 'pie'].label },
+        values: { chartName: PartitionChartsMeta[newShape === 'pie' ? 'donut' : 'pie'].label },
         description: 'chartName is already translated',
       }),
       score: 0.1,
@@ -125,7 +149,7 @@ export function suggestions({
   }
 
   if (
-    groups.length <= MAX_TREEMAP_BUCKETS &&
+    groups.length <= PartitionChartsMeta.treemap.maxBuckets &&
     (!subVisualizationId || subVisualizationId === 'treemap')
   ) {
     results.push({
@@ -174,7 +198,7 @@ export function suggestions({
   }
 
   if (
-    groups.length <= MAX_MOSAIC_BUCKETS &&
+    groups.length <= PartitionChartsMeta.mosaic.maxBuckets &&
     (!subVisualizationId || subVisualizationId === 'mosaic')
   ) {
     results.push({
@@ -216,6 +240,49 @@ export function suggestions({
     });
   }
 
+  if (
+    groups.length <= PartitionChartsMeta.waffle.maxBuckets &&
+    (!subVisualizationId || subVisualizationId === 'waffle')
+  ) {
+    results.push({
+      title: i18n.translate('xpack.lens.pie.waffleSuggestionLabel', {
+        defaultMessage: 'As Waffle',
+      }),
+      score: state?.shape === 'waffle' ? 0.7 : 0.5,
+      state: {
+        shape: 'waffle',
+        palette: mainPalette || state?.palette,
+        layers: [
+          state?.layers[0]
+            ? {
+                ...state.layers[0],
+                layerId: table.layerId,
+                groups: groups.map((col) => col.columnId),
+                metric: metricColumnId,
+                categoryDisplay: 'default',
+                layerType: layerTypes.DATA,
+              }
+            : {
+                layerId: table.layerId,
+                groups: groups.map((col) => col.columnId),
+                metric: metricColumnId,
+                numberDisplay: 'percent',
+                categoryDisplay: 'default',
+                legendDisplay: 'default',
+                nestedLegend: false,
+                layerType: layerTypes.DATA,
+              },
+        ],
+      },
+      previewIcon: 'bullseye',
+      hide:
+        groups.length !== 1 ||
+        table.changeType === 'reduced' ||
+        hasIntervalScale(groups) ||
+        (state && state.shape === 'waffle'),
+    });
+  }
+
   return [...results]
     .map((suggestion) => ({
       ...suggestion,
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 23003a4ec3404..7bb7da9b3223e 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -17,36 +17,13 @@ import {
 } from '@elastic/eui';
 import type { Position } from '@elastic/charts';
 import type { PaletteRegistry } from 'src/plugins/charts/public';
-import { DEFAULT_PERCENT_DECIMALS, CHART_NAMES } from './constants';
+import { DEFAULT_PERCENT_DECIMALS } from './constants';
+import { PartitionChartsMeta } from './partition_charts_meta';
 import type { PieVisualizationState, SharedPieLayerState } from '../../common/expressions';
 import { VisualizationDimensionEditorProps, VisualizationToolbarProps } from '../types';
 import { ToolbarPopover, LegendSettingsPopover, useDebouncedValue } from '../shared_components';
 import { PalettePicker } from '../shared_components';
 
-const numberOptions: Array<{
-  value: SharedPieLayerState['numberDisplay'];
-  inputDisplay: string;
-}> = [
-  {
-    value: 'hidden',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.hiddenNumbersLabel', {
-      defaultMessage: 'Hide from chart',
-    }),
-  },
-  {
-    value: 'percent',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.showPercentValuesLabel', {
-      defaultMessage: 'Show percent',
-    }),
-  },
-  {
-    value: 'value',
-    inputDisplay: i18n.translate('xpack.lens.pieChart.showFormatterValuesLabel', {
-      defaultMessage: 'Show value',
-    }),
-  },
-];
-
 const legendOptions: Array<{
   value: SharedPieLayerState['legendDisplay'];
   label: string;
@@ -81,6 +58,8 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   if (!layer) {
     return null;
   }
+  const { categoryOptions, numberOptions } = PartitionChartsMeta[state.shape];
+
   return (
     <EuiFlexGroup gutterSize="none" justifyContent="spaceBetween" responsive={false}>
       <ToolbarPopover
@@ -91,7 +70,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
         groupPosition="left"
         buttonDataTestSubj="lnsLabelsButton"
       >
-        {state.shape && CHART_NAMES[state.shape].categoryOptions.length ? (
+        {categoryOptions.length ? (
           <EuiFormRow
             label={i18n.translate('xpack.lens.pieChart.labelPositionLabel', {
               defaultMessage: 'Position',
@@ -102,7 +81,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
             <EuiSuperSelect
               compressed
               valueOfSelected={layer.categoryDisplay}
-              options={CHART_NAMES[state.shape].categoryOptions}
+              options={categoryOptions}
               onChange={(option) => {
                 setState({
                   ...state,
@@ -112,27 +91,32 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
             />
           </EuiFormRow>
         ) : null}
-        <EuiFormRow
-          label={i18n.translate('xpack.lens.pieChart.numberLabels', {
-            defaultMessage: 'Values',
-          })}
-          fullWidth
-          display="columnCompressed"
-        >
-          <EuiSuperSelect
-            compressed
-            disabled={layer.categoryDisplay === 'hide'}
-            valueOfSelected={layer.categoryDisplay === 'hide' ? 'hidden' : layer.numberDisplay}
-            options={numberOptions}
-            onChange={(option) => {
-              setState({
-                ...state,
-                layers: [{ ...layer, numberDisplay: option }],
-              });
-            }}
-          />
-        </EuiFormRow>
-        <EuiHorizontalRule margin="s" />
+
+        {numberOptions.length ? (
+          <EuiFormRow
+            label={i18n.translate('xpack.lens.pieChart.numberLabels', {
+              defaultMessage: 'Values',
+            })}
+            fullWidth
+            display="columnCompressed"
+          >
+            <EuiSuperSelect
+              compressed
+              disabled={layer.categoryDisplay === 'hide'}
+              valueOfSelected={layer.categoryDisplay === 'hide' ? 'hidden' : layer.numberDisplay}
+              options={numberOptions}
+              onChange={(option) => {
+                setState({
+                  ...state,
+                  layers: [{ ...layer, numberDisplay: option }],
+                });
+              }}
+            />
+          </EuiFormRow>
+        ) : null}
+
+        {numberOptions.length + categoryOptions.length ? <EuiHorizontalRule margin="s" /> : null}
+
         <EuiFormRow
           label={i18n.translate('xpack.lens.pieChart.percentDecimalsLabel', {
             defaultMessage: 'Maximum decimal places for percent',
diff --git a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
index f72a6e5bef11e..eec82d8ed57af 100644
--- a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
@@ -20,8 +20,9 @@ import { toExpression, toPreviewExpression } from './to_expression';
 import type { PieLayerState, PieVisualizationState } from '../../common/expressions';
 import { layerTypes } from '../../common';
 import { suggestions } from './suggestions';
-import { CHART_NAMES, MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS } from './constants';
+import { PartitionChartsMeta } from './partition_charts_meta';
 import { DimensionEditor, PieToolbar } from './toolbar';
+import { checkTableForContainsSmallValues } from './render_helpers';
 
 function newLayerState(layerId: string): PieLayerState {
   return {
@@ -65,33 +66,13 @@ export const getPieVisualization = ({
 }): Visualization<PieVisualizationState> => ({
   id: 'lnsPie',
 
-  visualizationTypes: [
-    {
-      id: 'donut',
-      icon: CHART_NAMES.donut.icon,
-      label: CHART_NAMES.donut.label,
-      groupLabel: CHART_NAMES.donut.groupLabel,
-    },
-    {
-      id: 'pie',
-      icon: CHART_NAMES.pie.icon,
-      label: CHART_NAMES.pie.label,
-      groupLabel: CHART_NAMES.pie.groupLabel,
-    },
-    {
-      id: 'treemap',
-      icon: CHART_NAMES.treemap.icon,
-      label: CHART_NAMES.treemap.label,
-      groupLabel: CHART_NAMES.treemap.groupLabel,
-    },
-    {
-      id: 'mosaic',
-      icon: CHART_NAMES.mosaic.icon,
-      label: CHART_NAMES.mosaic.label,
-      showExperimentalBadge: true,
-      groupLabel: CHART_NAMES.mosaic.groupLabel,
-    },
-  ],
+  visualizationTypes: Object.entries(PartitionChartsMeta).map(([key, meta]) => ({
+    id: key,
+    icon: meta.icon,
+    label: meta.label,
+    groupLabel: meta.groupLabel,
+    showExperimentalBadge: meta.isExperimental,
+  })),
 
   getVisualizationTypeId(state) {
     return state.shape;
@@ -109,7 +90,7 @@ export const getPieVisualization = ({
   },
 
   getDescription(state) {
-    return CHART_NAMES[state.shape] ?? CHART_NAMES.pie;
+    return PartitionChartsMeta[state.shape] ?? PartitionChartsMeta.pie;
   },
 
   switchVisualizationType: (visualizationTypeId, state) => ({
@@ -161,25 +142,25 @@ export const getPieVisualization = ({
       };
 
       switch (state.shape) {
-        case 'mosaic':
-        case 'treemap':
+        case 'donut':
+        case 'pie':
           return {
             ...baseProps,
-            groupLabel: i18n.translate('xpack.lens.pie.treemapGroupLabel', {
-              defaultMessage: 'Group by',
+            groupLabel: i18n.translate('xpack.lens.pie.sliceGroupLabel', {
+              defaultMessage: 'Slice by',
             }),
-            supportsMoreColumns: sortedColumns.length < MAX_TREEMAP_BUCKETS,
-            dataTestSubj: 'lnsPie_groupByDimensionPanel',
-            requiredMinDimensionCount: state.shape === 'mosaic' ? 2 : undefined,
+            supportsMoreColumns: sortedColumns.length < PartitionChartsMeta.pie.maxBuckets,
+            dataTestSubj: 'lnsPie_sliceByDimensionPanel',
           };
         default:
           return {
             ...baseProps,
-            groupLabel: i18n.translate('xpack.lens.pie.sliceGroupLabel', {
-              defaultMessage: 'Slice by',
+            groupLabel: i18n.translate('xpack.lens.pie.treemapGroupLabel', {
+              defaultMessage: 'Group by',
             }),
-            supportsMoreColumns: sortedColumns.length < MAX_PIE_BUCKETS,
-            dataTestSubj: 'lnsPie_sliceByDimensionPanel',
+            supportsMoreColumns: sortedColumns.length < PartitionChartsMeta[state.shape].maxBuckets,
+            dataTestSubj: 'lnsPie_groupByDimensionPanel',
+            requiredMinDimensionCount: PartitionChartsMeta[state.shape].requiredMinDimensionCount,
           };
       }
     };
@@ -271,33 +252,53 @@ export const getPieVisualization = ({
     if (state?.layers.length === 0 || !frame.activeData) {
       return;
     }
-
-    const metricColumnsWithArrayValues = [];
+    const warningMessages = [];
 
     for (const layer of state.layers) {
       const { layerId, metric } = layer;
-      const rows = frame.activeData[layerId] && frame.activeData[layerId].rows;
+      const rows = frame.activeData[layerId]?.rows;
+      const numericColumn = frame.activeData[layerId]?.columns.find(
+        ({ meta }) => meta?.type === 'number'
+      );
+
       if (!rows || !metric) {
         break;
       }
-      const columnToLabel = frame.datasourceLayers[layerId].getOperationForColumnId(metric)?.label;
 
+      if (
+        numericColumn &&
+        state.shape === 'waffle' &&
+        checkTableForContainsSmallValues(frame.activeData[layerId], numericColumn.id, 1)
+      ) {
+        warningMessages.push(
+          <FormattedMessage
+            id="xpack.lens.pie.smallValuesWarningMessage"
+            defaultMessage="The received data contains too small values that can be incorrectly visualized in the {shape} chart"
+            values={{
+              shape: <strong>{state.shape}</strong>,
+            }}
+          />
+        );
+      }
+
+      const columnToLabel = frame.datasourceLayers[layerId].getOperationForColumnId(metric)?.label;
       const hasArrayValues = rows.some((row) => Array.isArray(row[metric]));
       if (hasArrayValues) {
-        metricColumnsWithArrayValues.push(columnToLabel || metric);
+        warningMessages.push(
+          <FormattedMessage
+            key={columnToLabel || metric}
+            id="xpack.lens.pie.arrayValues"
+            defaultMessage="{label} contains array values. Your visualization may not render as
+        expected."
+            values={{
+              label: <strong>{columnToLabel || metric}</strong>,
+            }}
+          />
+        );
       }
     }
-    return metricColumnsWithArrayValues.map((label) => (
-      <FormattedMessage
-        key={label}
-        id="xpack.lens.pie.arrayValues"
-        defaultMessage="{label} contains array values. Your visualization may not render as
-        expected."
-        values={{
-          label: <strong>{label}</strong>,
-        }}
-      />
-    ));
+
+    return warningMessages;
   },
 
   getErrorMessages(state) {

From 3a58f8841782cb55236168a97a59a0d8cf67bca6 Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Tue, 23 Nov 2021 18:15:16 +0300
Subject: [PATCH 02/18] add showExtraLegend for waffle

---
 .../public/pie_visualization/partition_charts_meta.ts  | 10 ++++++++--
 .../lens/public/pie_visualization/render_function.tsx  |  3 ++-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index b88a457cc8f9e..90d55430c5d8a 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -34,7 +34,10 @@ interface PartitionChartMeta {
   maxBuckets: number;
   isExperimental?: boolean;
   requiredMinDimensionCount?: number;
-  flatLegend?: boolean;
+  legend?: {
+    flat?: boolean;
+    showValues?: boolean;
+  };
 }
 
 const groupLabel = i18n.translate('xpack.lens.pie.groupLabel', {
@@ -156,6 +159,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     numberOptions: [],
     maxBuckets: 1,
     isExperimental: true,
-    flatLegend: true,
+    legend: {
+      flat: true,
+      showValues: true,
+    },
   },
 };
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 f2faed801b797..93ed429e07746 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -323,7 +323,8 @@ export function PieComponent(
                 bucketColumns.length > 1 &&
                 !isTreemapOrMosaicShape(shape)))
           }
-          flatLegend={PartitionChartsMeta[shape].flatLegend}
+          flatLegend={PartitionChartsMeta[shape].legend?.flat}
+          showLegendExtra={PartitionChartsMeta[shape].legend?.showValues}
           legendPosition={legendPosition || Position.Right}
           legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */}
           onElementClick={props.interactive ?? true ? onElementClickHandler : undefined}

From 7291eefe6df68cc413653e9d084d3fc08ef2629e Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Wed, 24 Nov 2021 14:12:14 +0300
Subject: [PATCH 03/18] add tests

---
 .../pie_visualization/render_helpers.test.ts  |  57 ++++++++
 .../pie_visualization/suggestions.test.ts     | 129 ++++++++++++++++++
 2 files changed, 186 insertions(+)

diff --git a/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts b/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts
index dd27632b36e44..d86500ff8a4fa 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts
@@ -13,6 +13,7 @@ import {
   getFilterContext,
   byDataColorPaletteMap,
   extractUniqTermsMap,
+  checkTableForContainsSmallValues,
 } from './render_helpers';
 import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks';
 
@@ -317,4 +318,60 @@ describe('render helpers', () => {
       );
     });
   });
+
+  describe('#checkTableForContainsSmallValues', () => {
+    let datatable: Datatable;
+    const columnId = 'foo';
+
+    beforeEach(() => {
+      datatable = {
+        rows: [],
+      } as unknown as Datatable;
+    });
+
+    it('should return true if the data contains values less than the target percentage (1)', () => {
+      datatable.rows = [
+        {
+          [columnId]: 80,
+        },
+        {
+          [columnId]: 20,
+        },
+        {
+          [columnId]: 1,
+        },
+      ];
+      expect(checkTableForContainsSmallValues(datatable, columnId, 1)).toBeTruthy();
+    });
+
+    it('should return true if the data contains values less than the target percentage (42)', () => {
+      datatable.rows = [
+        {
+          [columnId]: 58,
+        },
+        {
+          [columnId]: 42,
+        },
+        {
+          [columnId]: 1,
+        },
+      ];
+      expect(checkTableForContainsSmallValues(datatable, columnId, 42)).toBeTruthy();
+    });
+
+    it('should return false if the data contains values greater than the target percentage', () => {
+      datatable.rows = [
+        {
+          [columnId]: 22,
+        },
+        {
+          [columnId]: 56,
+        },
+        {
+          [columnId]: 12,
+        },
+      ];
+      expect(checkTableForContainsSmallValues(datatable, columnId, 1)).toBeFalsy();
+    });
+  });
 });
diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
index 30e5c22d2af5e..92dde282da502 100644
--- a/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.test.ts
@@ -921,4 +921,133 @@ describe('suggestions', () => {
       ).toMatchInlineSnapshot(`Array []`);
     });
   });
+
+  describe('waffle', () => {
+    it('should reject when currently active and unchanged data', () => {
+      expect(
+        suggestions({
+          table: {
+            layerId: 'first',
+            isMultiRow: true,
+            columns: [],
+            changeType: 'unchanged',
+          },
+          state: {
+            shape: 'waffle',
+            layers: [
+              {
+                layerId: 'first',
+                layerType: layerTypes.DATA,
+                groups: [],
+                metric: 'a',
+
+                numberDisplay: 'hidden',
+                categoryDisplay: 'default',
+                legendDisplay: 'default',
+              },
+            ],
+          },
+          keptLayerIds: ['first'],
+        })
+      ).toHaveLength(0);
+    });
+
+    it('waffle type should be added only in case of 1 group', () => {
+      expect(
+        suggestions({
+          table: {
+            layerId: 'first',
+            isMultiRow: true,
+            columns: [
+              {
+                columnId: 'a',
+                operation: { label: 'Top 5', dataType: 'string' as DataType, isBucketed: true },
+              },
+              {
+                columnId: 'b',
+                operation: { label: 'Count', dataType: 'number' as DataType, isBucketed: false },
+              },
+            ],
+            changeType: 'unchanged',
+          },
+          state: {
+            shape: 'waffle',
+            layers: [
+              {
+                layerId: 'first',
+                layerType: layerTypes.DATA,
+                groups: ['a', 'b'],
+                metric: 'c',
+
+                numberDisplay: 'hidden',
+                categoryDisplay: 'inside',
+                legendDisplay: 'show',
+                percentDecimals: 0,
+                legendMaxLines: 1,
+                truncateLegend: true,
+                nestedLegend: true,
+              },
+            ],
+          },
+          keptLayerIds: ['first'],
+        }).filter(({ hide, state }) => !hide && state.shape === 'waffle')
+      ).toMatchInlineSnapshot(`Array []`);
+    });
+
+    it('waffle type should be added only in case of 1 group (negative test)', () => {
+      const meta: Parameters<typeof suggestions>[0] = {
+        table: {
+          layerId: 'first',
+          isMultiRow: true,
+          columns: [
+            {
+              columnId: 'c',
+              operation: { label: 'Count', dataType: 'number' as DataType, isBucketed: false },
+            },
+          ],
+          changeType: 'unchanged',
+        },
+        state: {
+          shape: 'pie',
+          layers: [
+            {
+              layerId: 'first',
+              layerType: layerTypes.DATA,
+              groups: ['a', 'b'],
+              metric: 'c',
+
+              numberDisplay: 'hidden',
+              categoryDisplay: 'inside',
+              legendDisplay: 'show',
+              percentDecimals: 0,
+              legendMaxLines: 1,
+              truncateLegend: true,
+              nestedLegend: true,
+            },
+          ],
+        },
+        keptLayerIds: ['first'],
+      };
+
+      // test with no group
+      expect(
+        suggestions(meta).filter(({ hide, state }) => !hide && state.shape === 'waffle')
+      ).toMatchInlineSnapshot(`Array []`);
+
+      meta.table.columns.push({
+        columnId: 'b',
+        operation: { label: 'Top 6', dataType: 'string' as DataType, isBucketed: true },
+      });
+
+      meta.table.columns.push({
+        columnId: 'c',
+        operation: { label: 'Top 7', dataType: 'string' as DataType, isBucketed: true },
+      });
+
+      // test with 2 groups
+      expect(
+        suggestions(meta).filter(({ hide, state }) => !hide && state.shape === 'waffle')
+      ).toMatchInlineSnapshot(`Array []`);
+    });
+  });
 });

From 34f6cb62487e7b0a8f4040b4902f9407fd5f07a6 Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Thu, 25 Nov 2021 17:12:59 +0300
Subject: [PATCH 04/18] resolved 1 and 5

---
 .../pie_visualization/partition_charts_meta.ts  | 17 ++++++++++++++++-
 .../pie_visualization/render_function.tsx       | 13 +++++++------
 .../public/pie_visualization/visualization.tsx  |  1 +
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index 90d55430c5d8a..caeffa5250784 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -17,6 +17,7 @@ import { LensIconChartWaffle } from '../assets/chart_waffle';
 
 import type { SharedPieLayerState } from '../../common/expressions';
 import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
+import type { DatatableColumn } from '../../../../../src/plugins/expressions';
 
 interface PartitionChartMeta {
   icon: ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => JSX.Element;
@@ -34,9 +35,10 @@ interface PartitionChartMeta {
   maxBuckets: number;
   isExperimental?: boolean;
   requiredMinDimensionCount?: number;
-  legend?: {
+  legend: {
     flat?: boolean;
     showValues?: boolean;
+    getShowLegendDefault?: (bucketColumns: DatatableColumn[]) => boolean;
   };
 }
 
@@ -112,6 +114,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     categoryOptions,
     numberOptions,
     maxBuckets: 3,
+    legend: {
+      getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
+    },
   },
   pie: {
     icon: LensIconChartPie,
@@ -123,6 +128,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     categoryOptions,
     numberOptions,
     maxBuckets: 3,
+    legend: {
+      getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
+    },
   },
   treemap: {
     icon: LensIconChartTreemap,
@@ -134,6 +142,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     categoryOptions: categoryOptionsTreemap,
     numberOptions,
     maxBuckets: 2,
+    legend: {
+      getShowLegendDefault: () => false,
+    },
   },
   mosaic: {
     icon: LensIconChartMosaic,
@@ -147,6 +158,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     maxBuckets: 2,
     isExperimental: true,
     requiredMinDimensionCount: 2,
+    legend: {
+      getShowLegendDefault: () => false,
+    },
   },
   waffle: {
     icon: LensIconChartWaffle,
@@ -162,6 +176,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     legend: {
       flat: true,
       showValues: true,
+      getShowLegendDefault: () => true,
     },
   },
 };
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 09acce5c47322..b09bc05aa82b8 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -210,8 +210,10 @@ export function PieComponent(
     };
   });
 
+  const { legend, partitionType: partitionLayout, label: chartType } = PartitionChartsMeta[shape];
+
   const config: RecursivePartial<PartitionConfig> = {
-    partitionLayout: PartitionChartsMeta[shape].partitionType,
+    partitionLayout,
     fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily,
     outerSizeRatio: 1,
     specialFirstInnermostSector: true,
@@ -293,7 +295,7 @@ export function PieComponent(
           id="xpack.lens.pie.pieWithNegativeWarningLabel"
           defaultMessage="{chartType} charts can't render with negative values."
           values={{
-            chartType: PartitionChartsMeta[shape].label,
+            chartType,
           }}
         />
       </EuiText>
@@ -320,11 +322,10 @@ export function PieComponent(
             !hideLabels &&
             (legendDisplay === 'show' ||
               (legendDisplay === 'default' &&
-                bucketColumns.length > 1 &&
-                !isTreemapOrMosaicShape(shape)))
+                (legend.getShowLegendDefault?.(bucketColumns) ?? false)))
           }
-          flatLegend={PartitionChartsMeta[shape].legend?.flat}
-          showLegendExtra={PartitionChartsMeta[shape].legend?.showValues}
+          flatLegend={legend.flat}
+          showLegendExtra={legend.showValues}
           legendPosition={legendPosition || Position.Right}
           legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */}
           onElementClick={props.interactive ?? true ? onElementClickHandler : undefined}
diff --git a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
index 51698bc3dd43f..0eb56ce090aff 100644
--- a/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/visualization.tsx
@@ -276,6 +276,7 @@ export const getPieVisualization = ({
       if (
         numericColumn &&
         state.shape === 'waffle' &&
+        layer.groups.length &&
         checkTableForContainsSmallValues(frame.activeData[layerId], numericColumn.id, 1)
       ) {
         warningMessages.push(

From 33ee2beb9d0f04a346a2d1b8ca1e0c6d747f6c27 Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Thu, 25 Nov 2021 17:54:23 +0300
Subject: [PATCH 05/18] resolved 6

---
 .../partition_charts_meta.ts                  | 58 ++++++++++++-------
 .../public/pie_visualization/to_expression.ts |  6 +-
 .../lens/public/pie_visualization/toolbar.tsx |  7 ++-
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index caeffa5250784..932b9e9500090 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -24,17 +24,20 @@ interface PartitionChartMeta {
   label: string;
   partitionType: PartitionLayout;
   groupLabel: string;
-  categoryOptions: Array<{
-    value: SharedPieLayerState['categoryDisplay'];
-    inputDisplay: string;
-  }>;
-  numberOptions: Array<{
-    value: SharedPieLayerState['numberDisplay'];
-    inputDisplay: string;
-  }>;
   maxBuckets: number;
   isExperimental?: boolean;
   requiredMinDimensionCount?: number;
+  toolbarPopover: {
+    isDisabled?: boolean;
+    categoryOptions: Array<{
+      value: SharedPieLayerState['categoryDisplay'];
+      inputDisplay: string;
+    }>;
+    numberOptions: Array<{
+      value: SharedPieLayerState['numberDisplay'];
+      inputDisplay: string;
+    }>;
+  };
   legend: {
     flat?: boolean;
     showValues?: boolean;
@@ -46,7 +49,7 @@ const groupLabel = i18n.translate('xpack.lens.pie.groupLabel', {
   defaultMessage: 'Proportion',
 });
 
-const categoryOptions: PartitionChartMeta['categoryOptions'] = [
+const categoryOptions: PartitionChartMeta['toolbarPopover']['categoryOptions'] = [
   {
     value: 'default',
     inputDisplay: i18n.translate('xpack.lens.pieChart.showCategoriesLabel', {
@@ -67,7 +70,7 @@ const categoryOptions: PartitionChartMeta['categoryOptions'] = [
   },
 ];
 
-const categoryOptionsTreemap: PartitionChartMeta['categoryOptions'] = [
+const categoryOptionsTreemap: PartitionChartMeta['toolbarPopover']['categoryOptions'] = [
   {
     value: 'default',
     inputDisplay: i18n.translate('xpack.lens.pieChart.showTreemapCategoriesLabel', {
@@ -82,7 +85,7 @@ const categoryOptionsTreemap: PartitionChartMeta['categoryOptions'] = [
   },
 ];
 
-const numberOptions: PartitionChartMeta['numberOptions'] = [
+const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
   {
     value: 'hidden',
     inputDisplay: i18n.translate('xpack.lens.pieChart.hiddenNumbersLabel', {
@@ -111,9 +114,11 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     }),
     partitionType: PartitionLayout.sunburst,
     groupLabel,
-    categoryOptions,
-    numberOptions,
     maxBuckets: 3,
+    toolbarPopover: {
+      categoryOptions,
+      numberOptions,
+    },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
     },
@@ -125,9 +130,11 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     }),
     partitionType: PartitionLayout.sunburst,
     groupLabel,
-    categoryOptions,
-    numberOptions,
     maxBuckets: 3,
+    toolbarPopover: {
+      categoryOptions,
+      numberOptions,
+    },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
     },
@@ -139,9 +146,11 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     }),
     partitionType: PartitionLayout.treemap,
     groupLabel,
-    categoryOptions: categoryOptionsTreemap,
-    numberOptions,
     maxBuckets: 2,
+    toolbarPopover: {
+      categoryOptions: categoryOptionsTreemap,
+      numberOptions,
+    },
     legend: {
       getShowLegendDefault: () => false,
     },
@@ -153,14 +162,16 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     }),
     partitionType: PartitionLayout.mosaic,
     groupLabel,
-    categoryOptions: [],
-    numberOptions,
     maxBuckets: 2,
     isExperimental: true,
-    requiredMinDimensionCount: 2,
+    toolbarPopover: {
+      categoryOptions: [],
+      numberOptions,
+    },
     legend: {
       getShowLegendDefault: () => false,
     },
+    requiredMinDimensionCount: 2,
   },
   waffle: {
     icon: LensIconChartWaffle,
@@ -169,10 +180,13 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     }),
     partitionType: PartitionLayout.waffle,
     groupLabel,
-    categoryOptions: [],
-    numberOptions: [],
     maxBuckets: 1,
     isExperimental: true,
+    toolbarPopover: {
+      isDisabled: true,
+      categoryOptions: [],
+      numberOptions: [],
+    },
     legend: {
       flat: true,
       showValues: true,
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 fd754906ceb02..e13fbf62708ee 100644
--- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
@@ -55,7 +55,11 @@ function expressionHelper(
           categoryDisplay: [layer.categoryDisplay],
           legendDisplay: [layer.legendDisplay],
           legendPosition: [layer.legendPosition || 'right'],
-          percentDecimals: [layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS],
+          percentDecimals: [
+            state.shape === 'waffle'
+              ? DEFAULT_PERCENT_DECIMALS
+              : layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS,
+          ],
           legendMaxLines: [layer.legendMaxLines ?? 1],
           truncateLegend: [layer.truncateLegend ?? true],
           nestedLegend: [!!layer.nestedLegend],
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 7bb7da9b3223e..195a72cca9fed 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -58,7 +58,11 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   if (!layer) {
     return null;
   }
-  const { categoryOptions, numberOptions } = PartitionChartsMeta[state.shape];
+  const {
+    categoryOptions,
+    numberOptions,
+    isDisabled: isToolbarPopoverDisabled,
+  } = PartitionChartsMeta[state.shape].toolbarPopover;
 
   return (
     <EuiFlexGroup gutterSize="none" justifyContent="spaceBetween" responsive={false}>
@@ -66,6 +70,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
         title={i18n.translate('xpack.lens.pieChart.valuesLabel', {
           defaultMessage: 'Labels',
         })}
+        isDisabled={Boolean(isToolbarPopoverDisabled)}
         type="labels"
         groupPosition="left"
         buttonDataTestSubj="lnsLabelsButton"

From 76ff6e92ed2084dd55e4b71aa70466b153bfa5d3 Mon Sep 17 00:00:00 2001
From: Alexey Antonov <alexwizp@gmail.com>
Date: Wed, 1 Dec 2021 14:17:04 +0300
Subject: [PATCH 06/18] add sortPredicate for waffle chart type

---
 .../partition_charts_meta.ts                  | 20 ++++++++++++++++++-
 .../pie_visualization/render_function.tsx     | 14 ++-----------
 .../public/pie_visualization/suggestions.ts   | 10 +++++-----
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index 932b9e9500090..4f16ab01ba19c 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -6,7 +6,7 @@
  */
 
 import { i18n } from '@kbn/i18n';
-import { PartitionLayout } from '@elastic/charts';
+import { ArrayEntry, PartitionLayout } from '@elastic/charts';
 import type { EuiIconProps } from '@elastic/eui';
 
 import { LensIconChartDonut } from '../assets/chart_donut';
@@ -43,6 +43,10 @@ interface PartitionChartMeta {
     showValues?: boolean;
     getShowLegendDefault?: (bucketColumns: DatatableColumn[]) => boolean;
   };
+  sortPredicate?: (
+    bucketColumns: DatatableColumn[],
+    sortingMap: Record<string, number>
+  ) => (node1: ArrayEntry, node2: ArrayEntry) => number;
 }
 
 const groupLabel = i18n.translate('xpack.lens.pie.groupLabel', {
@@ -172,6 +176,16 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       getShowLegendDefault: () => false,
     },
     requiredMinDimensionCount: 2,
+    sortPredicate:
+      (bucketColumns, sortingMap) =>
+      ([name1, node1], [, node2]) => {
+        // Sorting for first group
+        if (bucketColumns.length === 1 || (node1.children.length && name1 in sortingMap)) {
+          return sortingMap[name1];
+        }
+        // Sorting for second group
+        return node2.value - node1.value;
+      },
   },
   waffle: {
     icon: LensIconChartWaffle,
@@ -192,5 +206,9 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       showValues: true,
       getShowLegendDefault: () => true,
     },
+    sortPredicate:
+      () =>
+      ([, node1], [, node2]) =>
+        node2.value - node1.value,
   },
 };
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 b09bc05aa82b8..539d69207f5f9 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -127,7 +127,7 @@ export function PieComponent(
     );
   }
 
-  let sortingMap: Record<string, number>;
+  let sortingMap: Record<string, number> = {};
   if (shape === 'mosaic') {
     sortingMap = extractUniqTermsMap(firstTable, bucketColumns[0].id);
   }
@@ -146,17 +146,7 @@ export function PieComponent(
         return String(d);
       },
       fillLabel,
-      sortPredicate:
-        shape === 'mosaic'
-          ? ([name1, node1], [, node2]) => {
-              // Sorting for first group
-              if (bucketColumns.length === 1 || (node1.children.length && name1 in sortingMap)) {
-                return sortingMap[name1];
-              }
-              // Sorting for second group
-              return node2.value - node1.value;
-            }
-          : undefined,
+      sortPredicate: PartitionChartsMeta[shape].sortPredicate?.(bucketColumns, sortingMap),
       shape: {
         fillColor: (d) => {
           const seriesLayers: SeriesLayer[] = [];
diff --git a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
index c0adf7befa1fc..f638bfd908be4 100644
--- a/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/suggestions.ts
@@ -52,6 +52,10 @@ function hasCustomSuggestionsExists(shape: PieChartTypes | string | undefined) {
   return shape ? ['treemap', 'waffle', 'mosaic'].includes(shape) : false;
 }
 
+const maximumGroupLength = Math.max(
+  ...Object.values(PartitionChartsMeta).map(({ maxBuckets }) => maxBuckets)
+);
+
 export function suggestions({
   table,
   state,
@@ -67,11 +71,7 @@ export function suggestions({
 
   const [groups, metrics] = partition(table.columns, (col) => col.operation.isBucketed);
 
-  if (
-    metrics.length > 1 ||
-    groups.length >
-      Math.max(...Object.values(PartitionChartsMeta).map(({ maxBuckets }) => maxBuckets))
-  ) {
+  if (metrics.length > 1 || groups.length > maximumGroupLength) {
     return [];
   }
 

From 137a82d6a26960be2ae18051db26983d1456210e Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Wed, 1 Dec 2021 17:00:13 +0300
Subject: [PATCH 07/18] [Lens] Pie and donuts should have a size ratio setting

---
 .../common/expressions/pie_chart/pie_chart.ts |  8 ++
 .../common/expressions/pie_chart/types.ts     |  2 +
 .../public/pie_visualization/constants.ts     |  8 ++
 .../partition_charts_meta.ts                  | 37 +++++++++
 .../pie_visualization/render_function.tsx     |  6 +-
 .../public/pie_visualization/to_expression.ts |  8 +-
 .../lens/public/pie_visualization/toolbar.tsx | 78 +++++++++++++++++--
 7 files changed, 138 insertions(+), 9 deletions(-)

diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
index 053b46e480c7b..e7b40ef218802 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
@@ -97,6 +97,14 @@ export const pie: ExpressionFunctionDefinition<
       help: '',
       types: ['palette'],
     },
+    pieSizeRatio: {
+      types: ['number'],
+      help: '',
+    },
+    donutInnerAreaRatio: {
+      types: ['number'],
+      help: '',
+    },
   },
   inputTypes: ['lens_multitable'],
   fn(data: LensMultiTable, args: PieExpressionArgs) {
diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
index 8c9ec4e5a54e7..eae58136afa85 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
@@ -19,6 +19,8 @@ export interface SharedPieLayerState {
   legendPosition?: 'left' | 'right' | 'top' | 'bottom';
   nestedLegend?: boolean;
   percentDecimals?: number;
+  pieSizeRatio?: number;
+  donutInnerAreaRatio?: number;
   legendMaxLines?: number;
   truncateLegend?: boolean;
 }
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index bfb263b415891..14594a76abcbb 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -6,3 +6,11 @@
  */
 
 export const DEFAULT_PERCENT_DECIMALS = 2;
+
+export const DEFAULT_DONUT_INNER_AREA_RATIO = 0.3;
+
+export enum PIE_SIZE_RATIO {
+  SMALL = 0.6,
+  MEDIUM = 0.8,
+  LARGE = 1,
+}
diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index 4f16ab01ba19c..1e1e38a2121f6 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -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 { PIE_SIZE_RATIO } from './constants';
 
 import type { SharedPieLayerState } from '../../common/expressions';
 import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
@@ -29,6 +30,7 @@ interface PartitionChartMeta {
   requiredMinDimensionCount?: number;
   toolbarPopover: {
     isDisabled?: boolean;
+    hasInnerAreaSizeSetting?: boolean;
     categoryOptions: Array<{
       value: SharedPieLayerState['categoryDisplay'];
       inputDisplay: string;
@@ -37,6 +39,11 @@ interface PartitionChartMeta {
       value: SharedPieLayerState['numberDisplay'];
       inputDisplay: string;
     }>;
+    sizeRatioOptions: Array<{
+      id: string;
+      value: PIE_SIZE_RATIO;
+      label: string;
+    }>;
   };
   legend: {
     flat?: boolean;
@@ -110,6 +117,30 @@ const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
   },
 ];
 
+const sizeRatioOptions: PartitionChartMeta['toolbarPopover']['sizeRatioOptions'] = [
+  {
+    id: 'pieSizeOption-small',
+    value: PIE_SIZE_RATIO.SMALL,
+    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.small', {
+      defaultMessage: 'Small',
+    }),
+  },
+  {
+    id: 'pieSizeOption-medium',
+    value: PIE_SIZE_RATIO.MEDIUM,
+    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.medium', {
+      defaultMessage: 'Medium',
+    }),
+  },
+  {
+    id: 'pieSizeOption-large',
+    value: PIE_SIZE_RATIO.LARGE,
+    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.large', {
+      defaultMessage: 'Large',
+    }),
+  },
+];
+
 export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
   donut: {
     icon: LensIconChartDonut,
@@ -122,6 +153,8 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
+      sizeRatioOptions,
+      hasInnerAreaSizeSetting: true,
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -138,6 +171,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
+      sizeRatioOptions,
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -154,6 +188,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: categoryOptionsTreemap,
       numberOptions,
+      sizeRatioOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -171,6 +206,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: [],
       numberOptions,
+      sizeRatioOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -200,6 +236,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       isDisabled: true,
       categoryOptions: [],
       numberOptions: [],
+      sizeRatioOptions: [],
     },
     legend: {
       flat: true,
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 539d69207f5f9..de36dbd270c3d 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -82,6 +82,8 @@ export function PieComponent(
     legendPosition,
     nestedLegend,
     percentDecimals,
+    pieSizeRatio,
+    donutInnerAreaRatio,
     legendMaxLines,
     truncateLegend,
     hideLabels,
@@ -205,7 +207,7 @@ export function PieComponent(
   const config: RecursivePartial<PartitionConfig> = {
     partitionLayout,
     fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily,
-    outerSizeRatio: 1,
+    outerSizeRatio: pieSizeRatio,
     specialFirstInnermostSector: true,
     minFontSize: 10,
     maxFontSize: 16,
@@ -228,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' ? donutInnerAreaRatio : 0;
 
     if (hideLabels || categoryDisplay === 'hide') {
       // Force all labels to be linked, then prevent links from showing
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 e13fbf62708ee..9f1f747a34253 100644
--- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
@@ -8,7 +8,11 @@
 import { Ast } from '@kbn/interpreter/common';
 import { PaletteRegistry } from 'src/plugins/charts/public';
 import { Operation, DatasourcePublicAPI } from '../types';
-import { DEFAULT_PERCENT_DECIMALS } from './constants';
+import {
+  DEFAULT_DONUT_INNER_AREA_RATIO,
+  DEFAULT_PERCENT_DECIMALS,
+  PIE_SIZE_RATIO,
+} from './constants';
 import type { PieVisualizationState } from '../../common/expressions';
 
 export function toExpression(
@@ -55,6 +59,8 @@ function expressionHelper(
           categoryDisplay: [layer.categoryDisplay],
           legendDisplay: [layer.legendDisplay],
           legendPosition: [layer.legendPosition || 'right'],
+          pieSizeRatio: [layer.pieSizeRatio ?? PIE_SIZE_RATIO.LARGE],
+          donutInnerAreaRatio: [layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO],
           percentDecimals: [
             state.shape === 'waffle'
               ? DEFAULT_PERCENT_DECIMALS
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 195a72cca9fed..6a494ad4891f8 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -14,10 +14,11 @@ import {
   EuiSuperSelect,
   EuiRange,
   EuiHorizontalRule,
+  EuiButtonGroup,
 } from '@elastic/eui';
 import type { Position } from '@elastic/charts';
 import type { PaletteRegistry } from 'src/plugins/charts/public';
-import { DEFAULT_PERCENT_DECIMALS } from './constants';
+import { DEFAULT_DONUT_INNER_AREA_RATIO, DEFAULT_PERCENT_DECIMALS } from './constants';
 import { PartitionChartsMeta } from './partition_charts_meta';
 import type { PieVisualizationState, SharedPieLayerState } from '../../common/expressions';
 import { VisualizationDimensionEditorProps, VisualizationToolbarProps } from '../types';
@@ -52,6 +53,10 @@ const legendOptions: Array<{
   },
 ];
 
+const sizeLabel = i18n.translate('xpack.lens.pieChart.sizeLabel', {
+  defaultMessage: 'Size',
+});
+
 export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationState>) {
   const { state, setState } = props;
   const layer = state.layers[0];
@@ -61,6 +66,8 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   const {
     categoryOptions,
     numberOptions,
+    sizeRatioOptions,
+    hasInnerAreaSizeSetting,
     isDisabled: isToolbarPopoverDisabled,
   } = PartitionChartsMeta[state.shape].toolbarPopover;
 
@@ -129,7 +136,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           fullWidth
           display="rowCompressed"
         >
-          <DecimalPlaceSlider
+          <DebouncedValueSlider
             value={layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS}
             setValue={(value) => {
               setState({
@@ -137,9 +144,59 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
                 layers: [{ ...layer, percentDecimals: value }],
               });
             }}
+            dataTestSubj="indexPattern-dimension-formatDecimals"
           />
         </EuiFormRow>
       </ToolbarPopover>
+      <ToolbarPopover
+        title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
+          defaultMessage: 'Visual options',
+        })}
+        type="visualOptions"
+        groupPosition="center"
+        buttonDataTestSubj="lnsVisualOptionsButton"
+      >
+        <EuiFormRow label={sizeLabel} display="columnCompressed" fullWidth>
+          <EuiButtonGroup
+            isFullWidth
+            name="pieSizeRatio"
+            buttonSize="compressed"
+            legend={sizeLabel}
+            options={sizeRatioOptions}
+            idSelected={
+              sizeRatioOptions.find(({ value }) => value === layer.pieSizeRatio)?.id ||
+              'pieSizeOption-large'
+            }
+            onChange={(sizeId) => {
+              const pieSizeRatio = sizeRatioOptions.find(({ id }) => id === sizeId)?.value;
+              setState({ ...state, layers: [{ ...layer, pieSizeRatio }] });
+            }}
+          />
+        </EuiFormRow>
+        {hasInnerAreaSizeSetting && (
+          <EuiFormRow
+            label={i18n.translate('xpack.lens.pieChart.donutInnerAreaSize', {
+              defaultMessage: 'Size of inner empty area',
+            })}
+            fullWidth
+            display="rowCompressed"
+          >
+            <DebouncedValueSlider
+              min={20}
+              max={70}
+              step={10}
+              value={(layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO) * 100}
+              setValue={(value) => {
+                const donutInnerAreaRatio = value / 100;
+                setState({
+                  ...state,
+                  layers: [{ ...layer, donutInnerAreaRatio }],
+                });
+              }}
+            />
+          </EuiFormRow>
+        )}
+      </ToolbarPopover>
       <LegendSettingsPopover
         legendOptions={legendOptions}
         mode={layer.legendDisplay}
@@ -189,12 +246,20 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   );
 }
 
-const DecimalPlaceSlider = ({
+const DebouncedValueSlider = ({
   value,
   setValue,
+  dataTestSubj,
+  step,
+  min = 0,
+  max = 10,
 }: {
   value: number;
   setValue: (value: number) => void;
+  dataTestSubj?: string;
+  min?: number;
+  max?: number;
+  step?: number;
 }) => {
   const { inputValue, handleInputChange } = useDebouncedValue(
     {
@@ -205,10 +270,11 @@ const DecimalPlaceSlider = ({
   );
   return (
     <EuiRange
-      data-test-subj="indexPattern-dimension-formatDecimals"
+      data-test-subj={dataTestSubj}
       value={inputValue}
-      min={0}
-      max={10}
+      min={min}
+      max={max}
+      step={step}
       showInput
       compressed
       onChange={(e) => {

From 7a40ed1f96b868cec40e66a4bb578c10b400ae4d Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Wed, 1 Dec 2021 17:05:55 +0300
Subject: [PATCH 08/18] Add a missed condition

---
 .../lens/public/pie_visualization/toolbar.tsx | 94 ++++++++++---------
 1 file changed, 48 insertions(+), 46 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 6a494ad4891f8..ff996cbcec50b 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -148,55 +148,57 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           />
         </EuiFormRow>
       </ToolbarPopover>
-      <ToolbarPopover
-        title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
-          defaultMessage: 'Visual options',
-        })}
-        type="visualOptions"
-        groupPosition="center"
-        buttonDataTestSubj="lnsVisualOptionsButton"
-      >
-        <EuiFormRow label={sizeLabel} display="columnCompressed" fullWidth>
-          <EuiButtonGroup
-            isFullWidth
-            name="pieSizeRatio"
-            buttonSize="compressed"
-            legend={sizeLabel}
-            options={sizeRatioOptions}
-            idSelected={
-              sizeRatioOptions.find(({ value }) => value === layer.pieSizeRatio)?.id ||
-              'pieSizeOption-large'
-            }
-            onChange={(sizeId) => {
-              const pieSizeRatio = sizeRatioOptions.find(({ id }) => id === sizeId)?.value;
-              setState({ ...state, layers: [{ ...layer, pieSizeRatio }] });
-            }}
-          />
-        </EuiFormRow>
-        {hasInnerAreaSizeSetting && (
-          <EuiFormRow
-            label={i18n.translate('xpack.lens.pieChart.donutInnerAreaSize', {
-              defaultMessage: 'Size of inner empty area',
-            })}
-            fullWidth
-            display="rowCompressed"
-          >
-            <DebouncedValueSlider
-              min={20}
-              max={70}
-              step={10}
-              value={(layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO) * 100}
-              setValue={(value) => {
-                const donutInnerAreaRatio = value / 100;
-                setState({
-                  ...state,
-                  layers: [{ ...layer, donutInnerAreaRatio }],
-                });
+      {sizeRatioOptions.length ? (
+        <ToolbarPopover
+          title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
+            defaultMessage: 'Visual options',
+          })}
+          type="visualOptions"
+          groupPosition="center"
+          buttonDataTestSubj="lnsVisualOptionsButton"
+        >
+          <EuiFormRow label={sizeLabel} display="columnCompressed" fullWidth>
+            <EuiButtonGroup
+              isFullWidth
+              name="pieSizeRatio"
+              buttonSize="compressed"
+              legend={sizeLabel}
+              options={sizeRatioOptions}
+              idSelected={
+                sizeRatioOptions.find(({ value }) => value === layer.pieSizeRatio)?.id ||
+                'pieSizeOption-large'
+              }
+              onChange={(sizeId) => {
+                const pieSizeRatio = sizeRatioOptions.find(({ id }) => id === sizeId)?.value;
+                setState({ ...state, layers: [{ ...layer, pieSizeRatio }] });
               }}
             />
           </EuiFormRow>
-        )}
-      </ToolbarPopover>
+          {hasInnerAreaSizeSetting && (
+            <EuiFormRow
+              label={i18n.translate('xpack.lens.pieChart.donutInnerAreaSize', {
+                defaultMessage: 'Size of inner empty area',
+              })}
+              fullWidth
+              display="rowCompressed"
+            >
+              <DebouncedValueSlider
+                min={20}
+                max={70}
+                step={10}
+                value={(layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO) * 100}
+                setValue={(value) => {
+                  const donutInnerAreaRatio = value / 100;
+                  setState({
+                    ...state,
+                    layers: [{ ...layer, donutInnerAreaRatio }],
+                  });
+                }}
+              />
+            </EuiFormRow>
+          )}
+        </ToolbarPopover>
+      ) : null}
       <LegendSettingsPopover
         legendOptions={legendOptions}
         mode={layer.legendDisplay}

From f7907ad119cc4a42d034a517fa20b8aef61a3647 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Thu, 2 Dec 2021 14:31:31 +0300
Subject: [PATCH 09/18] Fix changing size for smallSlices

---
 .../lens/public/pie_visualization/render_function.tsx        | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

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 de36dbd270c3d..d207fb15f1da1 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -25,7 +25,7 @@ import {
 import { RenderMode } from 'src/plugins/expressions';
 import type { LensFilterEvent } from '../types';
 import { VisualizationContainer } from '../visualization_container';
-import { DEFAULT_PERCENT_DECIMALS } from './constants';
+import { DEFAULT_PERCENT_DECIMALS, PIE_SIZE_RATIO } from './constants';
 import { PartitionChartsMeta } from './partition_charts_meta';
 import type { FormatFactory } from '../../common';
 import type { PieExpressionProps } from '../../common/expressions';
@@ -246,7 +246,8 @@ export function PieComponent(
       const smallSlices = slices.filter((value) => value < 0.02).length;
       if (smallSlices) {
         // shrink up to 20% to give some room for the linked values
-        config.outerSizeRatio = 1 / (1 + Math.min(smallSlices * 0.05, 0.2));
+        config.outerSizeRatio =
+          (pieSizeRatio ?? PIE_SIZE_RATIO.LARGE) / (1 + Math.min(smallSlices * 0.05, 0.2));
       }
     }
   }

From 4833ef591f455fd0d6239f1f47fa11a78a0ef770 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Mon, 6 Dec 2021 17:03:14 +0300
Subject: [PATCH 10/18] Add donut inner area size setting to pie visualization
 and update it for lens

---
 .../pie/public/editor/collections.ts          | 25 +++++++
 .../pie/public/editor/components/pie.tsx      | 29 +++++++-
 .../vis_types/pie/public/editor/constants.ts  | 13 ++++
 src/plugins/vis_types/pie/public/pie_fn.ts    |  6 ++
 src/plugins/vis_types/pie/public/to_ast.ts    |  1 +
 .../vis_types/pie/public/types/types.ts       |  2 +
 .../vis_types/pie/public/utils/get_config.ts  |  2 +-
 .../vis_types/pie/public/vis_type/pie.ts      |  2 +
 .../common/expressions/pie_chart/pie_chart.ts |  6 +-
 .../common/expressions/pie_chart/types.ts     |  3 +-
 .../public/pie_visualization/constants.ts     | 10 ++-
 .../partition_charts_meta.ts                  | 65 +++++++++--------
 .../pie_visualization/render_function.tsx     | 12 ++--
 .../public/pie_visualization/to_expression.ts |  9 +--
 .../lens/public/pie_visualization/toolbar.tsx | 72 ++++++-------------
 15 files changed, 143 insertions(+), 114 deletions(-)
 create mode 100644 src/plugins/vis_types/pie/public/editor/constants.ts

diff --git a/src/plugins/vis_types/pie/public/editor/collections.ts b/src/plugins/vis_types/pie/public/editor/collections.ts
index d65e933a8835c..27d32f4b940aa 100644
--- a/src/plugins/vis_types/pie/public/editor/collections.ts
+++ b/src/plugins/vis_types/pie/public/editor/collections.ts
@@ -7,6 +7,7 @@
  */
 
 import { i18n } from '@kbn/i18n';
+import { DONUT_INNER_AREA_SIZE } from './constants';
 import { LabelPositions, ValueFormats } from '../types';
 
 export const getLabelPositions = [
@@ -38,3 +39,27 @@ export const getValuesFormats = [
     value: ValueFormats.VALUE,
   },
 ];
+
+export const donutInnerAreaSizeOptions = [
+  {
+    id: 'donutInnerAreaSizeOption-small',
+    value: DONUT_INNER_AREA_SIZE.SMALL,
+    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.small', {
+      defaultMessage: 'Small',
+    }),
+  },
+  {
+    id: 'donutInnerAreaSizeOption-medium',
+    value: DONUT_INNER_AREA_SIZE.MEDIUM,
+    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.medium', {
+      defaultMessage: 'Medium',
+    }),
+  },
+  {
+    id: 'donutInnerAreaSizeOption-large',
+    value: DONUT_INNER_AREA_SIZE.LARGE,
+    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.large', {
+      defaultMessage: 'Large',
+    }),
+  },
+];
diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 50e599b5ef5f3..0d9a05cdb3ae1 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -17,6 +17,7 @@ import {
   EuiIconTip,
   EuiFlexItem,
   EuiFlexGroup,
+  EuiButtonGroup,
 } from '@elastic/eui';
 import { i18n } from '@kbn/i18n';
 import { FormattedMessage } from '@kbn/i18n-react';
@@ -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 { donutInnerAreaSizeOptions, getLabelPositions, getValuesFormats } from '../collections';
 import { getLegendPositions } from '../positions';
 
 export interface PieOptionsProps extends VisEditorOptionsProps<PieVisParams>, PieTypeProps {}
 
+const donutInnerAreaSizeLabel = i18n.translate('visTypePie.editors.pie.donutInnerAreaSizeLabel', {
+  defaultMessage: 'Inner area size',
+});
+
 function DecimalSlider<ParamName extends string>({
   paramName,
   value,
@@ -116,6 +121,28 @@ const PieOptions = (props: PieOptionsProps) => {
           value={stateParams.isDonut}
           setValue={setValue}
         />
+        {stateParams.isDonut && (
+          <EuiFormRow label={donutInnerAreaSizeLabel} fullWidth>
+            <EuiButtonGroup
+              isFullWidth
+              name="donutInnerAreaSize"
+              buttonSize="compressed"
+              legend={donutInnerAreaSizeLabel}
+              options={donutInnerAreaSizeOptions}
+              idSelected={
+                donutInnerAreaSizeOptions.find(
+                  ({ value }) => value === stateParams.donutInnerAreaSize
+                )?.id || 'donutInnerAreaSizeOption-medium'
+              }
+              onChange={(sizeId) => {
+                const donutInnerAreaSize = donutInnerAreaSizeOptions.find(
+                  ({ id }) => id === sizeId
+                )?.value;
+                setValue('donutInnerAreaSize', donutInnerAreaSize);
+              }}
+            />
+          </EuiFormRow>
+        )}
         <BasicOptions {...props} legendPositions={getLegendPositions} />
         {props.showElasticChartsOptions && (
           <>
diff --git a/src/plugins/vis_types/pie/public/editor/constants.ts b/src/plugins/vis_types/pie/public/editor/constants.ts
new file mode 100644
index 0000000000000..04331cd15db4e
--- /dev/null
+++ b/src/plugins/vis_types/pie/public/editor/constants.ts
@@ -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 DONUT_INNER_AREA_SIZE {
+  SMALL = 0.2,
+  MEDIUM = 0.3,
+  LARGE = 0.5,
+}
diff --git a/src/plugins/vis_types/pie/public/pie_fn.ts b/src/plugins/vis_types/pie/public/pie_fn.ts
index 74e8127712399..75a578e9db99c 100644
--- a/src/plugins/vis_types/pie/public/pie_fn.ts
+++ b/src/plugins/vis_types/pie/public/pie_fn.ts
@@ -117,6 +117,12 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({
       }),
       default: false,
     },
+    donutInnerAreaSize: {
+      types: ['number'],
+      help: i18n.translate('visTypePie.function.args.donutInnerAreaSizeHelpText', {
+        defaultMessage: 'Defines donut inner empty area size',
+      }),
+    },
     palette: {
       types: ['string'],
       help: i18n.translate('visTypePie.function.args.paletteHelpText', {
diff --git a/src/plugins/vis_types/pie/public/to_ast.ts b/src/plugins/vis_types/pie/public/to_ast.ts
index fbfffbb77d5fb..060c6ab4f765f 100644
--- a/src/plugins/vis_types/pie/public/to_ast.ts
+++ b/src/plugins/vis_types/pie/public/to_ast.ts
@@ -54,6 +54,7 @@ export const toExpressionAst: VisToExpressionAst<PieVisParams> = async (vis, par
     maxLegendLines: vis.params.maxLegendLines,
     distinctColors: vis.params?.distinctColors,
     isDonut: vis.params.isDonut,
+    donutInnerAreaSize: vis.params.donutInnerAreaSize,
     palette: vis.params?.palette?.name,
     labels: prepareLabels(vis.params.labels),
     metric: schemas.metric.map(prepareDimension),
diff --git a/src/plugins/vis_types/pie/public/types/types.ts b/src/plugins/vis_types/pie/public/types/types.ts
index fb5efb5971805..25d3d24e44c3c 100644
--- a/src/plugins/vis_types/pie/public/types/types.ts
+++ b/src/plugins/vis_types/pie/public/types/types.ts
@@ -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 { DONUT_INNER_AREA_SIZE } from '../editor/constants';
 
 export interface Dimension {
   accessor: number;
@@ -38,6 +39,7 @@ interface PieCommonParams {
   maxLegendLines: number;
   distinctColors: boolean;
   isDonut: boolean;
+  donutInnerAreaSize?: DONUT_INNER_AREA_SIZE;
 }
 
 export interface LabelsParams {
diff --git a/src/plugins/vis_types/pie/public/utils/get_config.ts b/src/plugins/vis_types/pie/public/utils/get_config.ts
index 9f67155145820..e27954e6cb2fc 100644
--- a/src/plugins/vis_types/pie/public/utils/get_config.ts
+++ b/src/plugins/vis_types/pie/public/utils/get_config.ts
@@ -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.donutInnerAreaSize : 0,
     ...usingMargin,
   };
   if (!visParams.labels.show) {
diff --git a/src/plugins/vis_types/pie/public/vis_type/pie.ts b/src/plugins/vis_types/pie/public/vis_type/pie.ts
index 0d012ed95b5d9..b526a733d3eaa 100644
--- a/src/plugins/vis_types/pie/public/vis_type/pie.ts
+++ b/src/plugins/vis_types/pie/public/vis_type/pie.ts
@@ -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 { DONUT_INNER_AREA_SIZE } from '../editor/constants';
 
 export const getPieVisTypeDefinition = ({
   showElasticChartsOptions = false,
@@ -39,6 +40,7 @@ export const getPieVisTypeDefinition = ({
       maxLegendLines: 1,
       distinctColors: false,
       isDonut: true,
+      donutInnerAreaSize: DONUT_INNER_AREA_SIZE.MEDIUM,
       palette: {
         type: 'palette',
         name: 'default',
diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
index e7b40ef218802..8eddc48ca4535 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
@@ -97,11 +97,7 @@ export const pie: ExpressionFunctionDefinition<
       help: '',
       types: ['palette'],
     },
-    pieSizeRatio: {
-      types: ['number'],
-      help: '',
-    },
-    donutInnerAreaRatio: {
+    donutInnerAreaSize: {
       types: ['number'],
       help: '',
     },
diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
index eae58136afa85..423819e3c8593 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
@@ -19,8 +19,7 @@ export interface SharedPieLayerState {
   legendPosition?: 'left' | 'right' | 'top' | 'bottom';
   nestedLegend?: boolean;
   percentDecimals?: number;
-  pieSizeRatio?: number;
-  donutInnerAreaRatio?: number;
+  donutInnerAreaSize?: number;
   legendMaxLines?: number;
   truncateLegend?: boolean;
 }
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index 14594a76abcbb..b9d0954b17bce 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -7,10 +7,8 @@
 
 export const DEFAULT_PERCENT_DECIMALS = 2;
 
-export const DEFAULT_DONUT_INNER_AREA_RATIO = 0.3;
-
-export enum PIE_SIZE_RATIO {
-  SMALL = 0.6,
-  MEDIUM = 0.8,
-  LARGE = 1,
+export enum DONUT_INNER_AREA_SIZE {
+  SMALL = 0.2,
+  MEDIUM = 0.3,
+  LARGE = 0.5,
 }
diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index 1e1e38a2121f6..7b205e7a83cae 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -14,7 +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 { PIE_SIZE_RATIO } from './constants';
+import { DONUT_INNER_AREA_SIZE } from './constants';
 
 import type { SharedPieLayerState } from '../../common/expressions';
 import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
@@ -30,7 +30,6 @@ interface PartitionChartMeta {
   requiredMinDimensionCount?: number;
   toolbarPopover: {
     isDisabled?: boolean;
-    hasInnerAreaSizeSetting?: boolean;
     categoryOptions: Array<{
       value: SharedPieLayerState['categoryDisplay'];
       inputDisplay: string;
@@ -39,9 +38,9 @@ interface PartitionChartMeta {
       value: SharedPieLayerState['numberDisplay'];
       inputDisplay: string;
     }>;
-    sizeRatioOptions: Array<{
+    donutInnerAreaSizeOptions: Array<{
       id: string;
-      value: PIE_SIZE_RATIO;
+      value: DONUT_INNER_AREA_SIZE;
       label: string;
     }>;
   };
@@ -117,29 +116,30 @@ const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
   },
 ];
 
-const sizeRatioOptions: PartitionChartMeta['toolbarPopover']['sizeRatioOptions'] = [
-  {
-    id: 'pieSizeOption-small',
-    value: PIE_SIZE_RATIO.SMALL,
-    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.small', {
-      defaultMessage: 'Small',
-    }),
-  },
-  {
-    id: 'pieSizeOption-medium',
-    value: PIE_SIZE_RATIO.MEDIUM,
-    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.medium', {
-      defaultMessage: 'Medium',
-    }),
-  },
-  {
-    id: 'pieSizeOption-large',
-    value: PIE_SIZE_RATIO.LARGE,
-    label: i18n.translate('xpack.lens.pieChart.sizeRatioOptions.large', {
-      defaultMessage: 'Large',
-    }),
-  },
-];
+const donutInnerAreaSizeOptions: PartitionChartMeta['toolbarPopover']['donutInnerAreaSizeOptions'] =
+  [
+    {
+      id: 'donutInnerAreaSizeOption-small',
+      value: DONUT_INNER_AREA_SIZE.SMALL,
+      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.small', {
+        defaultMessage: 'Small',
+      }),
+    },
+    {
+      id: 'donutInnerAreaSizeOption-medium',
+      value: DONUT_INNER_AREA_SIZE.MEDIUM,
+      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.medium', {
+        defaultMessage: 'Medium',
+      }),
+    },
+    {
+      id: 'donutInnerAreaSizeOption-large',
+      value: DONUT_INNER_AREA_SIZE.LARGE,
+      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.large', {
+        defaultMessage: 'Large',
+      }),
+    },
+  ];
 
 export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
   donut: {
@@ -153,8 +153,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      sizeRatioOptions,
-      hasInnerAreaSizeSetting: true,
+      donutInnerAreaSizeOptions,
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -171,7 +170,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      sizeRatioOptions,
+      donutInnerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -188,7 +187,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: categoryOptionsTreemap,
       numberOptions,
-      sizeRatioOptions: [],
+      donutInnerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -206,7 +205,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: [],
       numberOptions,
-      sizeRatioOptions: [],
+      donutInnerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -236,7 +235,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       isDisabled: true,
       categoryOptions: [],
       numberOptions: [],
-      sizeRatioOptions: [],
+      donutInnerAreaSizeOptions: [],
     },
     legend: {
       flat: true,
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 d207fb15f1da1..5c6ea7b3f1ce4 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -25,7 +25,7 @@ import {
 import { RenderMode } from 'src/plugins/expressions';
 import type { LensFilterEvent } from '../types';
 import { VisualizationContainer } from '../visualization_container';
-import { DEFAULT_PERCENT_DECIMALS, PIE_SIZE_RATIO } from './constants';
+import { DEFAULT_PERCENT_DECIMALS } from './constants';
 import { PartitionChartsMeta } from './partition_charts_meta';
 import type { FormatFactory } from '../../common';
 import type { PieExpressionProps } from '../../common/expressions';
@@ -82,8 +82,7 @@ export function PieComponent(
     legendPosition,
     nestedLegend,
     percentDecimals,
-    pieSizeRatio,
-    donutInnerAreaRatio,
+    donutInnerAreaSize,
     legendMaxLines,
     truncateLegend,
     hideLabels,
@@ -207,7 +206,7 @@ export function PieComponent(
   const config: RecursivePartial<PartitionConfig> = {
     partitionLayout,
     fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily,
-    outerSizeRatio: pieSizeRatio,
+    outerSizeRatio: 1,
     specialFirstInnermostSector: true,
     minFontSize: 10,
     maxFontSize: 16,
@@ -230,7 +229,7 @@ export function PieComponent(
       config.fillLabel = { textColor: 'rgba(0,0,0,0)' };
     }
   } else {
-    config.emptySizeRatio = shape === 'donut' ? donutInnerAreaRatio : 0;
+    config.emptySizeRatio = shape === 'donut' ? donutInnerAreaSize : 0;
 
     if (hideLabels || categoryDisplay === 'hide') {
       // Force all labels to be linked, then prevent links from showing
@@ -246,8 +245,7 @@ export function PieComponent(
       const smallSlices = slices.filter((value) => value < 0.02).length;
       if (smallSlices) {
         // shrink up to 20% to give some room for the linked values
-        config.outerSizeRatio =
-          (pieSizeRatio ?? PIE_SIZE_RATIO.LARGE) / (1 + Math.min(smallSlices * 0.05, 0.2));
+        config.outerSizeRatio = 1 / (1 + Math.min(smallSlices * 0.05, 0.2));
       }
     }
   }
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 9f1f747a34253..af71fccc9cde3 100644
--- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
@@ -8,11 +8,7 @@
 import { Ast } from '@kbn/interpreter/common';
 import { PaletteRegistry } from 'src/plugins/charts/public';
 import { Operation, DatasourcePublicAPI } from '../types';
-import {
-  DEFAULT_DONUT_INNER_AREA_RATIO,
-  DEFAULT_PERCENT_DECIMALS,
-  PIE_SIZE_RATIO,
-} from './constants';
+import { DEFAULT_PERCENT_DECIMALS, DONUT_INNER_AREA_SIZE } from './constants';
 import type { PieVisualizationState } from '../../common/expressions';
 
 export function toExpression(
@@ -59,8 +55,7 @@ function expressionHelper(
           categoryDisplay: [layer.categoryDisplay],
           legendDisplay: [layer.legendDisplay],
           legendPosition: [layer.legendPosition || 'right'],
-          pieSizeRatio: [layer.pieSizeRatio ?? PIE_SIZE_RATIO.LARGE],
-          donutInnerAreaRatio: [layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO],
+          donutInnerAreaSize: [layer.donutInnerAreaSize ?? DONUT_INNER_AREA_SIZE.MEDIUM],
           percentDecimals: [
             state.shape === 'waffle'
               ? DEFAULT_PERCENT_DECIMALS
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index ff996cbcec50b..6dc417920d5ea 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -18,7 +18,7 @@ import {
 } from '@elastic/eui';
 import type { Position } from '@elastic/charts';
 import type { PaletteRegistry } from 'src/plugins/charts/public';
-import { DEFAULT_DONUT_INNER_AREA_RATIO, DEFAULT_PERCENT_DECIMALS } from './constants';
+import { DEFAULT_PERCENT_DECIMALS } from './constants';
 import { PartitionChartsMeta } from './partition_charts_meta';
 import type { PieVisualizationState, SharedPieLayerState } from '../../common/expressions';
 import { VisualizationDimensionEditorProps, VisualizationToolbarProps } from '../types';
@@ -53,8 +53,8 @@ const legendOptions: Array<{
   },
 ];
 
-const sizeLabel = i18n.translate('xpack.lens.pieChart.sizeLabel', {
-  defaultMessage: 'Size',
+const donutInnerAreaSizeLabel = i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeLabel', {
+  defaultMessage: 'Inner area size',
 });
 
 export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationState>) {
@@ -66,8 +66,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   const {
     categoryOptions,
     numberOptions,
-    sizeRatioOptions,
-    hasInnerAreaSizeSetting,
+    donutInnerAreaSizeOptions,
     isDisabled: isToolbarPopoverDisabled,
   } = PartitionChartsMeta[state.shape].toolbarPopover;
 
@@ -136,7 +135,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           fullWidth
           display="rowCompressed"
         >
-          <DebouncedValueSlider
+          <DecimalPlaceSlider
             value={layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS}
             setValue={(value) => {
               setState({
@@ -144,11 +143,10 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
                 layers: [{ ...layer, percentDecimals: value }],
               });
             }}
-            dataTestSubj="indexPattern-dimension-formatDecimals"
           />
         </EuiFormRow>
       </ToolbarPopover>
-      {sizeRatioOptions.length ? (
+      {donutInnerAreaSizeOptions.length ? (
         <ToolbarPopover
           title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
             defaultMessage: 'Visual options',
@@ -157,46 +155,25 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           groupPosition="center"
           buttonDataTestSubj="lnsVisualOptionsButton"
         >
-          <EuiFormRow label={sizeLabel} display="columnCompressed" fullWidth>
+          <EuiFormRow label={donutInnerAreaSizeLabel} display="columnCompressed" fullWidth>
             <EuiButtonGroup
               isFullWidth
-              name="pieSizeRatio"
+              name="donutInnerAreaSize"
               buttonSize="compressed"
-              legend={sizeLabel}
-              options={sizeRatioOptions}
+              legend={donutInnerAreaSizeLabel}
+              options={donutInnerAreaSizeOptions}
               idSelected={
-                sizeRatioOptions.find(({ value }) => value === layer.pieSizeRatio)?.id ||
-                'pieSizeOption-large'
+                donutInnerAreaSizeOptions.find(({ value }) => value === layer.donutInnerAreaSize)
+                  ?.id || 'donutInnerAreaSizeOption-medium'
               }
               onChange={(sizeId) => {
-                const pieSizeRatio = sizeRatioOptions.find(({ id }) => id === sizeId)?.value;
-                setState({ ...state, layers: [{ ...layer, pieSizeRatio }] });
+                const donutInnerAreaSize = donutInnerAreaSizeOptions.find(
+                  ({ id }) => id === sizeId
+                )?.value;
+                setState({ ...state, layers: [{ ...layer, donutInnerAreaSize }] });
               }}
             />
           </EuiFormRow>
-          {hasInnerAreaSizeSetting && (
-            <EuiFormRow
-              label={i18n.translate('xpack.lens.pieChart.donutInnerAreaSize', {
-                defaultMessage: 'Size of inner empty area',
-              })}
-              fullWidth
-              display="rowCompressed"
-            >
-              <DebouncedValueSlider
-                min={20}
-                max={70}
-                step={10}
-                value={(layer.donutInnerAreaRatio ?? DEFAULT_DONUT_INNER_AREA_RATIO) * 100}
-                setValue={(value) => {
-                  const donutInnerAreaRatio = value / 100;
-                  setState({
-                    ...state,
-                    layers: [{ ...layer, donutInnerAreaRatio }],
-                  });
-                }}
-              />
-            </EuiFormRow>
-          )}
         </ToolbarPopover>
       ) : null}
       <LegendSettingsPopover
@@ -248,20 +225,12 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   );
 }
 
-const DebouncedValueSlider = ({
+const DecimalPlaceSlider = ({
   value,
   setValue,
-  dataTestSubj,
-  step,
-  min = 0,
-  max = 10,
 }: {
   value: number;
   setValue: (value: number) => void;
-  dataTestSubj?: string;
-  min?: number;
-  max?: number;
-  step?: number;
 }) => {
   const { inputValue, handleInputChange } = useDebouncedValue(
     {
@@ -272,11 +241,10 @@ const DebouncedValueSlider = ({
   );
   return (
     <EuiRange
-      data-test-subj={dataTestSubj}
+      data-test-subj="indexPattern-dimension-formatDecimals"
       value={inputValue}
-      min={min}
-      max={max}
-      step={step}
+      min={0}
+      max={10}
       showInput
       compressed
       onChange={(e) => {

From d8eb0b5264631f2b9d21a92cd5cba072ca6daed5 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Mon, 6 Dec 2021 18:34:20 +0300
Subject: [PATCH 11/18] Update test and rename some constants

---
 .../public/__snapshots__/pie_fn.test.ts.snap  |  1 +
 .../pie/public/editor/components/pie.tsx      | 19 +++---
 .../vis_types/pie/public/pie_fn.test.ts       |  2 +
 .../partition_charts_meta.ts                  | 59 +++++++++----------
 .../lens/public/pie_visualization/toolbar.tsx | 18 +++---
 5 files changed, 52 insertions(+), 47 deletions(-)

diff --git a/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
index fb51717d1adc0..e9881544ccf8b 100644
--- a/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
+++ b/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
@@ -47,6 +47,7 @@ Object {
         "splitRow": undefined,
       },
       "distinctColors": false,
+      "donutInnerAreaSize": 0.3,
       "isDonut": true,
       "labels": Object {
         "percentDecimals": 2,
diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 0d9a05cdb3ae1..9a63b063ed95a 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -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,
@@ -101,6 +101,14 @@ const PieOptions = (props: PieOptionsProps) => {
     fetchPalettes();
   }, [props.palettes]);
 
+  const handleDonutInnerAreaSizeChange = useCallback(
+    (sizeId) => {
+      const donutInnerAreaSize = donutInnerAreaSizeOptions.find(({ id }) => id === sizeId)?.value;
+      setValue('donutInnerAreaSize', donutInnerAreaSize);
+    },
+    [setValue]
+  );
+
   return (
     <>
       <EuiPanel paddingSize="s">
@@ -132,14 +140,9 @@ const PieOptions = (props: PieOptionsProps) => {
               idSelected={
                 donutInnerAreaSizeOptions.find(
                   ({ value }) => value === stateParams.donutInnerAreaSize
-                )?.id || 'donutInnerAreaSizeOption-medium'
+                )?.id ?? 'donutInnerAreaSizeOption-medium'
               }
-              onChange={(sizeId) => {
-                const donutInnerAreaSize = donutInnerAreaSizeOptions.find(
-                  ({ id }) => id === sizeId
-                )?.value;
-                setValue('donutInnerAreaSize', donutInnerAreaSize);
-              }}
+              onChange={handleDonutInnerAreaSizeChange}
             />
           </EuiFormRow>
         )}
diff --git a/src/plugins/vis_types/pie/public/pie_fn.test.ts b/src/plugins/vis_types/pie/public/pie_fn.test.ts
index 9ba21cdc847e5..63bbd947d2dff 100644
--- a/src/plugins/vis_types/pie/public/pie_fn.test.ts
+++ b/src/plugins/vis_types/pie/public/pie_fn.test.ts
@@ -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 { DONUT_INNER_AREA_SIZE } from './editor/constants';
 
 describe('interpreter/functions#pie', () => {
   const fn = functionWrapper(createPieVisFn());
@@ -23,6 +24,7 @@ describe('interpreter/functions#pie', () => {
     addLegend: true,
     legendPosition: 'right',
     isDonut: true,
+    donutInnerAreaSize: DONUT_INNER_AREA_SIZE.MEDIUM,
     nestedLegend: true,
     truncateLegend: true,
     maxLegendLines: true,
diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index 7b205e7a83cae..ae9158e893e57 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -38,7 +38,7 @@ interface PartitionChartMeta {
       value: SharedPieLayerState['numberDisplay'];
       inputDisplay: string;
     }>;
-    donutInnerAreaSizeOptions: Array<{
+    innerAreaSizeOptions: Array<{
       id: string;
       value: DONUT_INNER_AREA_SIZE;
       label: string;
@@ -116,30 +116,29 @@ const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
   },
 ];
 
-const donutInnerAreaSizeOptions: PartitionChartMeta['toolbarPopover']['donutInnerAreaSizeOptions'] =
-  [
-    {
-      id: 'donutInnerAreaSizeOption-small',
-      value: DONUT_INNER_AREA_SIZE.SMALL,
-      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.small', {
-        defaultMessage: 'Small',
-      }),
-    },
-    {
-      id: 'donutInnerAreaSizeOption-medium',
-      value: DONUT_INNER_AREA_SIZE.MEDIUM,
-      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.medium', {
-        defaultMessage: 'Medium',
-      }),
-    },
-    {
-      id: 'donutInnerAreaSizeOption-large',
-      value: DONUT_INNER_AREA_SIZE.LARGE,
-      label: i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeOptions.large', {
-        defaultMessage: 'Large',
-      }),
-    },
-  ];
+const innerAreaSizeOptions: PartitionChartMeta['toolbarPopover']['innerAreaSizeOptions'] = [
+  {
+    id: 'innerAreaSizeOption-small',
+    value: DONUT_INNER_AREA_SIZE.SMALL,
+    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.small', {
+      defaultMessage: 'Small',
+    }),
+  },
+  {
+    id: 'innerAreaSizeOption-medium',
+    value: DONUT_INNER_AREA_SIZE.MEDIUM,
+    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.medium', {
+      defaultMessage: 'Medium',
+    }),
+  },
+  {
+    id: 'innerAreaSizeOption-large',
+    value: DONUT_INNER_AREA_SIZE.LARGE,
+    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.large', {
+      defaultMessage: 'Large',
+    }),
+  },
+];
 
 export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
   donut: {
@@ -153,7 +152,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      donutInnerAreaSizeOptions,
+      innerAreaSizeOptions,
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -170,7 +169,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      donutInnerAreaSizeOptions: [],
+      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -187,7 +186,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: categoryOptionsTreemap,
       numberOptions,
-      donutInnerAreaSizeOptions: [],
+      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -205,7 +204,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: [],
       numberOptions,
-      donutInnerAreaSizeOptions: [],
+      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -235,7 +234,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       isDisabled: true,
       categoryOptions: [],
       numberOptions: [],
-      donutInnerAreaSizeOptions: [],
+      innerAreaSizeOptions: [],
     },
     legend: {
       flat: true,
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 6dc417920d5ea..bde5e5fe99d27 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -53,7 +53,7 @@ const legendOptions: Array<{
   },
 ];
 
-const donutInnerAreaSizeLabel = i18n.translate('xpack.lens.pieChart.donutInnerAreaSizeLabel', {
+const innerAreaSizeLabel = i18n.translate('xpack.lens.pieChart.innerAreaSizeLabel', {
   defaultMessage: 'Inner area size',
 });
 
@@ -66,7 +66,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   const {
     categoryOptions,
     numberOptions,
-    donutInnerAreaSizeOptions,
+    innerAreaSizeOptions,
     isDisabled: isToolbarPopoverDisabled,
   } = PartitionChartsMeta[state.shape].toolbarPopover;
 
@@ -146,7 +146,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           />
         </EuiFormRow>
       </ToolbarPopover>
-      {donutInnerAreaSizeOptions.length ? (
+      {innerAreaSizeOptions.length ? (
         <ToolbarPopover
           title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
             defaultMessage: 'Visual options',
@@ -155,19 +155,19 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           groupPosition="center"
           buttonDataTestSubj="lnsVisualOptionsButton"
         >
-          <EuiFormRow label={donutInnerAreaSizeLabel} display="columnCompressed" fullWidth>
+          <EuiFormRow label={innerAreaSizeLabel} display="columnCompressed" fullWidth>
             <EuiButtonGroup
               isFullWidth
               name="donutInnerAreaSize"
               buttonSize="compressed"
-              legend={donutInnerAreaSizeLabel}
-              options={donutInnerAreaSizeOptions}
+              legend={innerAreaSizeLabel}
+              options={innerAreaSizeOptions}
               idSelected={
-                donutInnerAreaSizeOptions.find(({ value }) => value === layer.donutInnerAreaSize)
-                  ?.id || 'donutInnerAreaSizeOption-medium'
+                innerAreaSizeOptions.find(({ value }) => value === layer.donutInnerAreaSize)?.id ??
+                'innerAreaSizeOption-medium'
               }
               onChange={(sizeId) => {
-                const donutInnerAreaSize = donutInnerAreaSizeOptions.find(
+                const donutInnerAreaSize = innerAreaSizeOptions.find(
                   ({ id }) => id === sizeId
                 )?.value;
                 setState({ ...state, layers: [{ ...layer, donutInnerAreaSize }] });

From dd5c11c077d9774cb21115b847dd7e55255affd5 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Tue, 7 Dec 2021 11:51:07 +0300
Subject: [PATCH 12/18] Rename the setting

---
 .../public/__snapshots__/pie_fn.test.ts.snap  |  2 +-
 .../pie/public/editor/collections.ts          | 22 ++++++-------
 .../pie/public/editor/components/pie.tsx      | 25 +++++++--------
 .../vis_types/pie/public/editor/constants.ts  |  2 +-
 .../vis_types/pie/public/pie_fn.test.ts       |  4 +--
 src/plugins/vis_types/pie/public/pie_fn.ts    |  4 +--
 src/plugins/vis_types/pie/public/to_ast.ts    |  2 +-
 .../vis_types/pie/public/types/types.ts       |  4 +--
 .../vis_types/pie/public/utils/get_config.ts  |  2 +-
 .../vis_types/pie/public/vis_type/pie.ts      |  4 +--
 .../common/expressions/pie_chart/pie_chart.ts |  2 +-
 .../common/expressions/pie_chart/types.ts     |  2 +-
 .../public/pie_visualization/constants.ts     |  2 +-
 .../partition_charts_meta.ts                  | 32 ++++++++-----------
 .../pie_visualization/render_function.tsx     |  4 +--
 .../public/pie_visualization/to_expression.ts |  4 +--
 .../lens/public/pie_visualization/toolbar.tsx | 24 +++++++-------
 17 files changed, 67 insertions(+), 74 deletions(-)

diff --git a/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
index e9881544ccf8b..4298654af512d 100644
--- a/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
+++ b/src/plugins/vis_types/pie/public/__snapshots__/pie_fn.test.ts.snap
@@ -47,7 +47,7 @@ Object {
         "splitRow": undefined,
       },
       "distinctColors": false,
-      "donutInnerAreaSize": 0.3,
+      "emptySizeRatio": 0.3,
       "isDonut": true,
       "labels": Object {
         "percentDecimals": 2,
diff --git a/src/plugins/vis_types/pie/public/editor/collections.ts b/src/plugins/vis_types/pie/public/editor/collections.ts
index 27d32f4b940aa..64e4694eb449f 100644
--- a/src/plugins/vis_types/pie/public/editor/collections.ts
+++ b/src/plugins/vis_types/pie/public/editor/collections.ts
@@ -7,7 +7,7 @@
  */
 
 import { i18n } from '@kbn/i18n';
-import { DONUT_INNER_AREA_SIZE } from './constants';
+import { EMPTY_SIZE_RATIOS } from './constants';
 import { LabelPositions, ValueFormats } from '../types';
 
 export const getLabelPositions = [
@@ -40,25 +40,25 @@ export const getValuesFormats = [
   },
 ];
 
-export const donutInnerAreaSizeOptions = [
+export const emptySizeRatioOptions = [
   {
-    id: 'donutInnerAreaSizeOption-small',
-    value: DONUT_INNER_AREA_SIZE.SMALL,
-    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.small', {
+    id: 'emptySizeRatioOption-small',
+    value: EMPTY_SIZE_RATIOS.SMALL,
+    label: i18n.translate('visTypePie.emptySizeRatioOptions.small', {
       defaultMessage: 'Small',
     }),
   },
   {
-    id: 'donutInnerAreaSizeOption-medium',
-    value: DONUT_INNER_AREA_SIZE.MEDIUM,
-    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.medium', {
+    id: 'emptySizeRatioOption-medium',
+    value: EMPTY_SIZE_RATIOS.MEDIUM,
+    label: i18n.translate('visTypePie.emptySizeRatioOptions.medium', {
       defaultMessage: 'Medium',
     }),
   },
   {
-    id: 'donutInnerAreaSizeOption-large',
-    value: DONUT_INNER_AREA_SIZE.LARGE,
-    label: i18n.translate('visTypePie.donutInnerAreaSizeOptions.large', {
+    id: 'emptySizeRatioOption-large',
+    value: EMPTY_SIZE_RATIOS.LARGE,
+    label: i18n.translate('visTypePie.emptySizeRatioOptions.large', {
       defaultMessage: 'Large',
     }),
   },
diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 9a63b063ed95a..07c14db6e3d69 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -34,12 +34,12 @@ import { TruncateLabelsOption } from './truncate_labels';
 import { PaletteRegistry } from '../../../../../charts/public';
 import { DEFAULT_PERCENT_DECIMALS } from '../../../common';
 import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../../types';
-import { donutInnerAreaSizeOptions, getLabelPositions, getValuesFormats } from '../collections';
+import { emptySizeRatioOptions, getLabelPositions, getValuesFormats } from '../collections';
 import { getLegendPositions } from '../positions';
 
 export interface PieOptionsProps extends VisEditorOptionsProps<PieVisParams>, PieTypeProps {}
 
-const donutInnerAreaSizeLabel = i18n.translate('visTypePie.editors.pie.donutInnerAreaSizeLabel', {
+const emptySizeRatioLabel = i18n.translate('visTypePie.editors.pie.emptySizeRatioLabel', {
   defaultMessage: 'Inner area size',
 });
 
@@ -101,10 +101,10 @@ const PieOptions = (props: PieOptionsProps) => {
     fetchPalettes();
   }, [props.palettes]);
 
-  const handleDonutInnerAreaSizeChange = useCallback(
+  const handleEmptySizeRatioChange = useCallback(
     (sizeId) => {
-      const donutInnerAreaSize = donutInnerAreaSizeOptions.find(({ id }) => id === sizeId)?.value;
-      setValue('donutInnerAreaSize', donutInnerAreaSize);
+      const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value;
+      setValue('emptySizeRatio', emptySizeRatio);
     },
     [setValue]
   );
@@ -130,19 +130,18 @@ const PieOptions = (props: PieOptionsProps) => {
           setValue={setValue}
         />
         {stateParams.isDonut && (
-          <EuiFormRow label={donutInnerAreaSizeLabel} fullWidth>
+          <EuiFormRow label={emptySizeRatioLabel} fullWidth>
             <EuiButtonGroup
               isFullWidth
-              name="donutInnerAreaSize"
+              name="emptySizeRatio"
               buttonSize="compressed"
-              legend={donutInnerAreaSizeLabel}
-              options={donutInnerAreaSizeOptions}
+              legend={emptySizeRatioLabel}
+              options={emptySizeRatioOptions}
               idSelected={
-                donutInnerAreaSizeOptions.find(
-                  ({ value }) => value === stateParams.donutInnerAreaSize
-                )?.id ?? 'donutInnerAreaSizeOption-medium'
+                emptySizeRatioOptions.find(({ value }) => value === stateParams.emptySizeRatio)
+                  ?.id ?? 'emptySizeRatioOption-medium'
               }
-              onChange={handleDonutInnerAreaSizeChange}
+              onChange={handleEmptySizeRatioChange}
             />
           </EuiFormRow>
         )}
diff --git a/src/plugins/vis_types/pie/public/editor/constants.ts b/src/plugins/vis_types/pie/public/editor/constants.ts
index 04331cd15db4e..8789d351d4e65 100644
--- a/src/plugins/vis_types/pie/public/editor/constants.ts
+++ b/src/plugins/vis_types/pie/public/editor/constants.ts
@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-export enum DONUT_INNER_AREA_SIZE {
+export enum EMPTY_SIZE_RATIOS {
   SMALL = 0.2,
   MEDIUM = 0.3,
   LARGE = 0.5,
diff --git a/src/plugins/vis_types/pie/public/pie_fn.test.ts b/src/plugins/vis_types/pie/public/pie_fn.test.ts
index 63bbd947d2dff..d823d59cfdb82 100644
--- a/src/plugins/vis_types/pie/public/pie_fn.test.ts
+++ b/src/plugins/vis_types/pie/public/pie_fn.test.ts
@@ -10,7 +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 { DONUT_INNER_AREA_SIZE } from './editor/constants';
+import { EMPTY_SIZE_RATIOS } from './editor/constants';
 
 describe('interpreter/functions#pie', () => {
   const fn = functionWrapper(createPieVisFn());
@@ -24,7 +24,7 @@ describe('interpreter/functions#pie', () => {
     addLegend: true,
     legendPosition: 'right',
     isDonut: true,
-    donutInnerAreaSize: DONUT_INNER_AREA_SIZE.MEDIUM,
+    emptySizeRatio: EMPTY_SIZE_RATIOS.MEDIUM,
     nestedLegend: true,
     truncateLegend: true,
     maxLegendLines: true,
diff --git a/src/plugins/vis_types/pie/public/pie_fn.ts b/src/plugins/vis_types/pie/public/pie_fn.ts
index 75a578e9db99c..041ecb5b7e6e5 100644
--- a/src/plugins/vis_types/pie/public/pie_fn.ts
+++ b/src/plugins/vis_types/pie/public/pie_fn.ts
@@ -117,9 +117,9 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({
       }),
       default: false,
     },
-    donutInnerAreaSize: {
+    emptySizeRatio: {
       types: ['number'],
-      help: i18n.translate('visTypePie.function.args.donutInnerAreaSizeHelpText', {
+      help: i18n.translate('visTypePie.function.args.emptySizeRatioHelpText', {
         defaultMessage: 'Defines donut inner empty area size',
       }),
     },
diff --git a/src/plugins/vis_types/pie/public/to_ast.ts b/src/plugins/vis_types/pie/public/to_ast.ts
index 060c6ab4f765f..531b8516464f2 100644
--- a/src/plugins/vis_types/pie/public/to_ast.ts
+++ b/src/plugins/vis_types/pie/public/to_ast.ts
@@ -54,7 +54,7 @@ export const toExpressionAst: VisToExpressionAst<PieVisParams> = async (vis, par
     maxLegendLines: vis.params.maxLegendLines,
     distinctColors: vis.params?.distinctColors,
     isDonut: vis.params.isDonut,
-    donutInnerAreaSize: vis.params.donutInnerAreaSize,
+    emptySizeRatio: vis.params.emptySizeRatio,
     palette: vis.params?.palette?.name,
     labels: prepareLabels(vis.params.labels),
     metric: schemas.metric.map(prepareDimension),
diff --git a/src/plugins/vis_types/pie/public/types/types.ts b/src/plugins/vis_types/pie/public/types/types.ts
index 25d3d24e44c3c..4745ee0f95ed5 100644
--- a/src/plugins/vis_types/pie/public/types/types.ts
+++ b/src/plugins/vis_types/pie/public/types/types.ts
@@ -13,7 +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 { DONUT_INNER_AREA_SIZE } from '../editor/constants';
+import { EMPTY_SIZE_RATIOS } from '../editor/constants';
 
 export interface Dimension {
   accessor: number;
@@ -39,7 +39,7 @@ interface PieCommonParams {
   maxLegendLines: number;
   distinctColors: boolean;
   isDonut: boolean;
-  donutInnerAreaSize?: DONUT_INNER_AREA_SIZE;
+  emptySizeRatio?: EMPTY_SIZE_RATIOS;
 }
 
 export interface LabelsParams {
diff --git a/src/plugins/vis_types/pie/public/utils/get_config.ts b/src/plugins/vis_types/pie/public/utils/get_config.ts
index e27954e6cb2fc..67852a773d697 100644
--- a/src/plugins/vis_types/pie/public/utils/get_config.ts
+++ b/src/plugins/vis_types/pie/public/utils/get_config.ts
@@ -54,7 +54,7 @@ export const getConfig = (
     sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill,
     sectorLineWidth: 1.5,
     circlePadding: 4,
-    emptySizeRatio: visParams.isDonut ? visParams.donutInnerAreaSize : 0,
+    emptySizeRatio: visParams.isDonut ? visParams.emptySizeRatio : 0,
     ...usingMargin,
   };
   if (!visParams.labels.show) {
diff --git a/src/plugins/vis_types/pie/public/vis_type/pie.ts b/src/plugins/vis_types/pie/public/vis_type/pie.ts
index b526a733d3eaa..c9129f4aedc23 100644
--- a/src/plugins/vis_types/pie/public/vis_type/pie.ts
+++ b/src/plugins/vis_types/pie/public/vis_type/pie.ts
@@ -14,7 +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 { DONUT_INNER_AREA_SIZE } from '../editor/constants';
+import { EMPTY_SIZE_RATIOS } from '../editor/constants';
 
 export const getPieVisTypeDefinition = ({
   showElasticChartsOptions = false,
@@ -40,7 +40,7 @@ export const getPieVisTypeDefinition = ({
       maxLegendLines: 1,
       distinctColors: false,
       isDonut: true,
-      donutInnerAreaSize: DONUT_INNER_AREA_SIZE.MEDIUM,
+      emptySizeRatio: EMPTY_SIZE_RATIOS.MEDIUM,
       palette: {
         type: 'palette',
         name: 'default',
diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
index 8eddc48ca4535..e66228267bed5 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/pie_chart.ts
@@ -97,7 +97,7 @@ export const pie: ExpressionFunctionDefinition<
       help: '',
       types: ['palette'],
     },
-    donutInnerAreaSize: {
+    emptySizeRatio: {
       types: ['number'],
       help: '',
     },
diff --git a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
index 423819e3c8593..a93dfaa845c7b 100644
--- a/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
+++ b/x-pack/plugins/lens/common/expressions/pie_chart/types.ts
@@ -19,7 +19,7 @@ export interface SharedPieLayerState {
   legendPosition?: 'left' | 'right' | 'top' | 'bottom';
   nestedLegend?: boolean;
   percentDecimals?: number;
-  donutInnerAreaSize?: number;
+  emptySizeRatio?: number;
   legendMaxLines?: number;
   truncateLegend?: boolean;
 }
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index b9d0954b17bce..17d2990522ba4 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -7,7 +7,7 @@
 
 export const DEFAULT_PERCENT_DECIMALS = 2;
 
-export enum DONUT_INNER_AREA_SIZE {
+export enum EMPTY_SIZE_RATIOS {
   SMALL = 0.2,
   MEDIUM = 0.3,
   LARGE = 0.5,
diff --git a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
index ae9158e893e57..2bafa5a1ff8e0 100644
--- a/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/partition_charts_meta.ts
@@ -14,7 +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 { DONUT_INNER_AREA_SIZE } from './constants';
+import { EMPTY_SIZE_RATIOS } from './constants';
 
 import type { SharedPieLayerState } from '../../common/expressions';
 import type { PieChartTypes } from '../../common/expressions/pie_chart/types';
@@ -38,9 +38,9 @@ interface PartitionChartMeta {
       value: SharedPieLayerState['numberDisplay'];
       inputDisplay: string;
     }>;
-    innerAreaSizeOptions: Array<{
+    emptySizeRatioOptions?: Array<{
       id: string;
-      value: DONUT_INNER_AREA_SIZE;
+      value: EMPTY_SIZE_RATIOS;
       label: string;
     }>;
   };
@@ -116,25 +116,25 @@ const numberOptions: PartitionChartMeta['toolbarPopover']['numberOptions'] = [
   },
 ];
 
-const innerAreaSizeOptions: PartitionChartMeta['toolbarPopover']['innerAreaSizeOptions'] = [
+const emptySizeRatioOptions: PartitionChartMeta['toolbarPopover']['emptySizeRatioOptions'] = [
   {
-    id: 'innerAreaSizeOption-small',
-    value: DONUT_INNER_AREA_SIZE.SMALL,
-    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.small', {
+    id: 'emptySizeRatioOption-small',
+    value: EMPTY_SIZE_RATIOS.SMALL,
+    label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.small', {
       defaultMessage: 'Small',
     }),
   },
   {
-    id: 'innerAreaSizeOption-medium',
-    value: DONUT_INNER_AREA_SIZE.MEDIUM,
-    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.medium', {
+    id: 'emptySizeRatioOption-medium',
+    value: EMPTY_SIZE_RATIOS.MEDIUM,
+    label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.medium', {
       defaultMessage: 'Medium',
     }),
   },
   {
-    id: 'innerAreaSizeOption-large',
-    value: DONUT_INNER_AREA_SIZE.LARGE,
-    label: i18n.translate('xpack.lens.pieChart.innerAreaSizeOptions.large', {
+    id: 'emptySizeRatioOption-large',
+    value: EMPTY_SIZE_RATIOS.LARGE,
+    label: i18n.translate('xpack.lens.pieChart.emptySizeRatioOptions.large', {
       defaultMessage: 'Large',
     }),
   },
@@ -152,7 +152,7 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      innerAreaSizeOptions,
+      emptySizeRatioOptions,
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -169,7 +169,6 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions,
       numberOptions,
-      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: (bucketColumns) => bucketColumns.length > 1,
@@ -186,7 +185,6 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: categoryOptionsTreemap,
       numberOptions,
-      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -204,7 +202,6 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
     toolbarPopover: {
       categoryOptions: [],
       numberOptions,
-      innerAreaSizeOptions: [],
     },
     legend: {
       getShowLegendDefault: () => false,
@@ -234,7 +231,6 @@ export const PartitionChartsMeta: Record<PieChartTypes, PartitionChartMeta> = {
       isDisabled: true,
       categoryOptions: [],
       numberOptions: [],
-      innerAreaSizeOptions: [],
     },
     legend: {
       flat: true,
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 5c6ea7b3f1ce4..d65d430115158 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -82,7 +82,7 @@ export function PieComponent(
     legendPosition,
     nestedLegend,
     percentDecimals,
-    donutInnerAreaSize,
+    emptySizeRatio,
     legendMaxLines,
     truncateLegend,
     hideLabels,
@@ -229,7 +229,7 @@ export function PieComponent(
       config.fillLabel = { textColor: 'rgba(0,0,0,0)' };
     }
   } else {
-    config.emptySizeRatio = shape === 'donut' ? donutInnerAreaSize : 0;
+    config.emptySizeRatio = shape === 'donut' ? emptySizeRatio : 0;
 
     if (hideLabels || categoryDisplay === 'hide') {
       // Force all labels to be linked, then prevent links from showing
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 af71fccc9cde3..9f87d2e18c267 100644
--- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
@@ -8,7 +8,7 @@
 import { Ast } from '@kbn/interpreter/common';
 import { PaletteRegistry } from 'src/plugins/charts/public';
 import { Operation, DatasourcePublicAPI } from '../types';
-import { DEFAULT_PERCENT_DECIMALS, DONUT_INNER_AREA_SIZE } from './constants';
+import { DEFAULT_PERCENT_DECIMALS, EMPTY_SIZE_RATIOS } from './constants';
 import type { PieVisualizationState } from '../../common/expressions';
 
 export function toExpression(
@@ -55,7 +55,7 @@ function expressionHelper(
           categoryDisplay: [layer.categoryDisplay],
           legendDisplay: [layer.legendDisplay],
           legendPosition: [layer.legendPosition || 'right'],
-          donutInnerAreaSize: [layer.donutInnerAreaSize ?? DONUT_INNER_AREA_SIZE.MEDIUM],
+          emptySizeRatio: [layer.emptySizeRatio ?? EMPTY_SIZE_RATIOS.MEDIUM],
           percentDecimals: [
             state.shape === 'waffle'
               ? DEFAULT_PERCENT_DECIMALS
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index bde5e5fe99d27..0842d591b5de7 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -53,7 +53,7 @@ const legendOptions: Array<{
   },
 ];
 
-const innerAreaSizeLabel = i18n.translate('xpack.lens.pieChart.innerAreaSizeLabel', {
+const emptySizeRatioLabel = i18n.translate('xpack.lens.pieChart.emptySizeRatioLabel', {
   defaultMessage: 'Inner area size',
 });
 
@@ -66,7 +66,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
   const {
     categoryOptions,
     numberOptions,
-    innerAreaSizeOptions,
+    emptySizeRatioOptions,
     isDisabled: isToolbarPopoverDisabled,
   } = PartitionChartsMeta[state.shape].toolbarPopover;
 
@@ -146,7 +146,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           />
         </EuiFormRow>
       </ToolbarPopover>
-      {innerAreaSizeOptions.length ? (
+      {emptySizeRatioOptions?.length ? (
         <ToolbarPopover
           title={i18n.translate('xpack.lens.pieChart.visualOptionsLabel', {
             defaultMessage: 'Visual options',
@@ -155,22 +155,20 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
           groupPosition="center"
           buttonDataTestSubj="lnsVisualOptionsButton"
         >
-          <EuiFormRow label={innerAreaSizeLabel} display="columnCompressed" fullWidth>
+          <EuiFormRow label={emptySizeRatioLabel} display="columnCompressed" fullWidth>
             <EuiButtonGroup
               isFullWidth
-              name="donutInnerAreaSize"
+              name="emptySizeRatio"
               buttonSize="compressed"
-              legend={innerAreaSizeLabel}
-              options={innerAreaSizeOptions}
+              legend={emptySizeRatioLabel}
+              options={emptySizeRatioOptions}
               idSelected={
-                innerAreaSizeOptions.find(({ value }) => value === layer.donutInnerAreaSize)?.id ??
-                'innerAreaSizeOption-medium'
+                emptySizeRatioOptions.find(({ value }) => value === layer.emptySizeRatio)?.id ??
+                'emptySizeRatioOption-medium'
               }
               onChange={(sizeId) => {
-                const donutInnerAreaSize = innerAreaSizeOptions.find(
-                  ({ id }) => id === sizeId
-                )?.value;
-                setState({ ...state, layers: [{ ...layer, donutInnerAreaSize }] });
+                const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value;
+                setState({ ...state, layers: [{ ...layer, emptySizeRatio }] });
               }}
             />
           </EuiFormRow>

From dae7adadb5572c4ab2f67e7f95e83c852c2a32ce Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Tue, 7 Dec 2021 14:03:22 +0300
Subject: [PATCH 13/18] Move handler to a separate useCallback function

---
 .../lens/public/pie_visualization/toolbar.tsx | 33 ++++++++++++++-----
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 0842d591b5de7..c2604a176417d 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -6,7 +6,7 @@
  */
 
 import './toolbar.scss';
-import React from 'react';
+import React, { useCallback } from 'react';
 import { i18n } from '@kbn/i18n';
 import {
   EuiFlexGroup,
@@ -60,9 +60,17 @@ const emptySizeRatioLabel = i18n.translate('xpack.lens.pieChart.emptySizeRatioLa
 export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationState>) {
   const { state, setState } = props;
   const layer = state.layers[0];
-  if (!layer) {
-    return null;
-  }
+
+  const onStateChange = useCallback(
+    (part: Record<string, unknown>) => {
+      setState({
+        ...state,
+        layers: [{ ...layer, ...part }],
+      });
+    },
+    [layer, state, setState]
+  );
+
   const {
     categoryOptions,
     numberOptions,
@@ -70,6 +78,18 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
     isDisabled: isToolbarPopoverDisabled,
   } = PartitionChartsMeta[state.shape].toolbarPopover;
 
+  const onEmptySizeRatioChange = useCallback(
+    (sizeId) => {
+      const emptySizeRatio = emptySizeRatioOptions?.find(({ id }) => id === sizeId)?.value;
+      onStateChange({ emptySizeRatio });
+    },
+    [emptySizeRatioOptions, onStateChange]
+  );
+
+  if (!layer) {
+    return null;
+  }
+
   return (
     <EuiFlexGroup gutterSize="none" justifyContent="spaceBetween" responsive={false}>
       <ToolbarPopover
@@ -166,10 +186,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
                 emptySizeRatioOptions.find(({ value }) => value === layer.emptySizeRatio)?.id ??
                 'emptySizeRatioOption-medium'
               }
-              onChange={(sizeId) => {
-                const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value;
-                setState({ ...state, layers: [{ ...layer, emptySizeRatio }] });
-              }}
+              onChange={onEmptySizeRatioChange}
             />
           </EuiFormRow>
         </ToolbarPopover>

From 3c62dedb8871d7f1732fe296117ff328fac2a0f7 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Tue, 7 Dec 2021 15:32:44 +0300
Subject: [PATCH 14/18] Update size ratios and add condition for legacy charts

---
 src/plugins/vis_types/pie/public/editor/components/pie.tsx | 2 +-
 src/plugins/vis_types/pie/public/editor/constants.ts       | 2 +-
 x-pack/plugins/lens/public/pie_visualization/constants.ts  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 07c14db6e3d69..41c0ac2717011 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -129,7 +129,7 @@ const PieOptions = (props: PieOptionsProps) => {
           value={stateParams.isDonut}
           setValue={setValue}
         />
-        {stateParams.isDonut && (
+        {props.showElasticChartsOptions && stateParams.isDonut && (
           <EuiFormRow label={emptySizeRatioLabel} fullWidth>
             <EuiButtonGroup
               isFullWidth
diff --git a/src/plugins/vis_types/pie/public/editor/constants.ts b/src/plugins/vis_types/pie/public/editor/constants.ts
index 8789d351d4e65..f1a1fdf21e07e 100644
--- a/src/plugins/vis_types/pie/public/editor/constants.ts
+++ b/src/plugins/vis_types/pie/public/editor/constants.ts
@@ -9,5 +9,5 @@
 export enum EMPTY_SIZE_RATIOS {
   SMALL = 0.2,
   MEDIUM = 0.3,
-  LARGE = 0.5,
+  LARGE = 0.7,
 }
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index 17d2990522ba4..22fb90c4d870f 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -10,5 +10,5 @@ export const DEFAULT_PERCENT_DECIMALS = 2;
 export enum EMPTY_SIZE_RATIOS {
   SMALL = 0.2,
   MEDIUM = 0.3,
-  LARGE = 0.5,
+  LARGE = 0.7,
 }

From 65e6f66a23dd640fbebe6394492fa379302e1d2d Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Wed, 8 Dec 2021 12:17:11 +0300
Subject: [PATCH 15/18] Fix merge conflict issue

---
 x-pack/plugins/lens/public/pie_visualization/toolbar.tsx | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 4723d46b088c9..0926250d4f812 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -122,9 +122,6 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
     });
   }, [layer, state.shape, onStateChange]);
 
-  if (!layer) {
-    return null;
-  }
   const {
     categoryOptions,
     numberOptions,

From 0bdd7da3f631e5f630b00eb6765bffd306848b8c Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Wed, 8 Dec 2021 14:57:24 +0300
Subject: [PATCH 16/18] Change constants order

---
 .../lens/public/pie_visualization/toolbar.tsx       | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 0926250d4f812..7b87831e08113 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -61,6 +61,12 @@ const emptySizeRatioLabel = i18n.translate('xpack.lens.pieChart.emptySizeRatioLa
 export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationState>) {
   const { state, setState } = props;
   const layer = state.layers[0];
+  const {
+    categoryOptions,
+    numberOptions,
+    emptySizeRatioOptions,
+    isDisabled: isToolbarPopoverDisabled,
+  } = PartitionChartsMeta[state.shape].toolbarPopover;
 
   const onStateChange = useCallback(
     (part: Record<string, unknown>) => {
@@ -122,13 +128,6 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
     });
   }, [layer, state.shape, onStateChange]);
 
-  const {
-    categoryOptions,
-    numberOptions,
-    emptySizeRatioOptions,
-    isDisabled: isToolbarPopoverDisabled,
-  } = PartitionChartsMeta[state.shape].toolbarPopover;
-
   const onEmptySizeRatioChange = useCallback(
     (sizeId) => {
       const emptySizeRatio = emptySizeRatioOptions?.find(({ id }) => id === sizeId)?.value;

From a9cb5ab89f88de6f23f09c34011a913c60472e89 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Thu, 9 Dec 2021 15:19:04 +0300
Subject: [PATCH 17/18] Add a couple of tests to check if the setting is
 displayed

---
 .../pie/public/editor/components/pie.test.tsx | 14 +++++++++++
 .../pie/public/editor/components/pie.tsx      |  1 +
 .../lens/public/pie_visualization/toolbar.tsx |  1 +
 .../test/functional/apps/lens/smokescreen.ts  | 24 +++++++++++++++++++
 .../test/functional/page_objects/lens_page.ts |  7 ++++++
 5 files changed, 47 insertions(+)

diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.test.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.test.tsx
index ac02b33b92add..d6dc4c0734e42 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.test.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.test.tsx
@@ -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);
+    });
+  });
 });
diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 41c0ac2717011..1a46bb01411d0 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -142,6 +142,7 @@ const PieOptions = (props: PieOptionsProps) => {
                   ?.id ?? 'emptySizeRatioOption-medium'
               }
               onChange={handleEmptySizeRatioChange}
+              data-test-subj="visTypePieEmptySizeRatioButtonGroup"
             />
           </EuiFormRow>
         )}
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index 4a0c4652b9330..c9cbe63c98d8c 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -228,6 +228,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
                 'emptySizeRatioOption-medium'
               }
               onChange={onEmptySizeRatioChange}
+              data-test-subj="lnsEmptySizeRatioButtonGroup"
             />
           </EuiFormRow>
         </ToolbarPopover>
diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts
index 7cacee6446723..34449f2d77307 100644
--- a/x-pack/test/functional/apps/lens/smokescreen.ts
+++ b/x-pack/test/functional/apps/lens/smokescreen.ts
@@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
   const testSubjects = getService('testSubjects');
   const elasticChart = getService('elasticChart');
   const filterBar = getService('filterBar');
+  const retry = getService('retry');
 
   describe('lens smokescreen tests', () => {
     it('should allow creation of lens xy chart', async () => {
@@ -766,5 +767,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
 
       await filterBar.removeFilter('extension.raw');
     });
+
+    it('should show visual options button group for a donut chart', async () => {
+      await PageObjects.visualize.navigateToNewVisualization();
+      await PageObjects.visualize.clickVisType('lens');
+      await PageObjects.lens.switchToVisualization('donut');
+
+      const hasVisualOptionsButton = await PageObjects.lens.hasVisualOptionsButton();
+      expect(hasVisualOptionsButton).to.be(true);
+
+      await PageObjects.lens.openVisualOptions();
+      await retry.try(async () => {
+        expect(await PageObjects.lens.hasEmptySizeRatioButtonGroup()).to.be(true);
+      });
+    });
+
+    it('should not show visual options button group for a pie chart', async () => {
+      await PageObjects.visualize.navigateToNewVisualization();
+      await PageObjects.visualize.clickVisType('lens');
+      await PageObjects.lens.switchToVisualization('pie');
+
+      const hasVisualOptionsButton = await PageObjects.lens.hasVisualOptionsButton();
+      expect(hasVisualOptionsButton).to.be(false);
+    });
   });
 }
diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts
index ed83e16e587ee..ef5a4e6b79c89 100644
--- a/x-pack/test/functional/page_objects/lens_page.ts
+++ b/x-pack/test/functional/page_objects/lens_page.ts
@@ -590,6 +590,9 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
       await colorPickerInput.type(color);
       await PageObjects.common.sleep(1000); // give time for debounced components to rerender
     },
+    hasVisualOptionsButton() {
+      return testSubjects.exists('lnsVisualOptionsButton');
+    },
     async openVisualOptions() {
       await retry.try(async () => {
         await testSubjects.click('lnsVisualOptionsButton');
@@ -1223,5 +1226,9 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
       const filterIn = await testSubjects.find(`legend-${value}-filterIn`);
       await filterIn.click();
     },
+
+    hasEmptySizeRatioButtonGroup() {
+      return testSubjects.exists('lnsEmptySizeRatioButtonGroup');
+    },
   });
 }

From af1899d272ed7c6cc941244d9d12d2bc52b1f71c Mon Sep 17 00:00:00 2001
From: Diana Derevyankina <dziyana_dzeraviankina@epam.com>
Date: Fri, 17 Dec 2021 18:25:30 +0300
Subject: [PATCH 18/18] Update ratio sizes

---
 src/plugins/vis_types/pie/public/editor/components/pie.tsx    | 2 +-
 src/plugins/vis_types/pie/public/editor/constants.ts          | 4 ++--
 src/plugins/vis_types/pie/public/pie_fn.test.ts               | 2 +-
 src/plugins/vis_types/pie/public/vis_type/pie.ts              | 2 +-
 x-pack/plugins/lens/public/pie_visualization/constants.ts     | 4 ++--
 x-pack/plugins/lens/public/pie_visualization/to_expression.ts | 2 +-
 x-pack/plugins/lens/public/pie_visualization/toolbar.tsx      | 2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
index 1a46bb01411d0..97f427d7b91b7 100644
--- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx
+++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx
@@ -139,7 +139,7 @@ const PieOptions = (props: PieOptionsProps) => {
               options={emptySizeRatioOptions}
               idSelected={
                 emptySizeRatioOptions.find(({ value }) => value === stateParams.emptySizeRatio)
-                  ?.id ?? 'emptySizeRatioOption-medium'
+                  ?.id ?? 'emptySizeRatioOption-small'
               }
               onChange={handleEmptySizeRatioChange}
               data-test-subj="visTypePieEmptySizeRatioButtonGroup"
diff --git a/src/plugins/vis_types/pie/public/editor/constants.ts b/src/plugins/vis_types/pie/public/editor/constants.ts
index f1a1fdf21e07e..6fd0c7ab0a4a6 100644
--- a/src/plugins/vis_types/pie/public/editor/constants.ts
+++ b/src/plugins/vis_types/pie/public/editor/constants.ts
@@ -7,7 +7,7 @@
  */
 
 export enum EMPTY_SIZE_RATIOS {
-  SMALL = 0.2,
-  MEDIUM = 0.3,
+  SMALL = 0.3,
+  MEDIUM = 0.54,
   LARGE = 0.7,
 }
diff --git a/src/plugins/vis_types/pie/public/pie_fn.test.ts b/src/plugins/vis_types/pie/public/pie_fn.test.ts
index d823d59cfdb82..9a9c2410481bd 100644
--- a/src/plugins/vis_types/pie/public/pie_fn.test.ts
+++ b/src/plugins/vis_types/pie/public/pie_fn.test.ts
@@ -24,7 +24,7 @@ describe('interpreter/functions#pie', () => {
     addLegend: true,
     legendPosition: 'right',
     isDonut: true,
-    emptySizeRatio: EMPTY_SIZE_RATIOS.MEDIUM,
+    emptySizeRatio: EMPTY_SIZE_RATIOS.SMALL,
     nestedLegend: true,
     truncateLegend: true,
     maxLegendLines: true,
diff --git a/src/plugins/vis_types/pie/public/vis_type/pie.ts b/src/plugins/vis_types/pie/public/vis_type/pie.ts
index 6ef0e5ec83e40..845b2bae1c89d 100644
--- a/src/plugins/vis_types/pie/public/vis_type/pie.ts
+++ b/src/plugins/vis_types/pie/public/vis_type/pie.ts
@@ -40,7 +40,7 @@ export const getPieVisTypeDefinition = ({
       maxLegendLines: 1,
       distinctColors: false,
       isDonut: true,
-      emptySizeRatio: EMPTY_SIZE_RATIOS.MEDIUM,
+      emptySizeRatio: EMPTY_SIZE_RATIOS.SMALL,
       palette: {
         type: 'palette',
         name: 'default',
diff --git a/x-pack/plugins/lens/public/pie_visualization/constants.ts b/x-pack/plugins/lens/public/pie_visualization/constants.ts
index 22fb90c4d870f..e32320bb75ff0 100644
--- a/x-pack/plugins/lens/public/pie_visualization/constants.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/constants.ts
@@ -8,7 +8,7 @@
 export const DEFAULT_PERCENT_DECIMALS = 2;
 
 export enum EMPTY_SIZE_RATIOS {
-  SMALL = 0.2,
-  MEDIUM = 0.3,
+  SMALL = 0.3,
+  MEDIUM = 0.54,
   LARGE = 0.7,
 }
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 9005136621b07..f7e76567743e4 100644
--- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
+++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts
@@ -58,7 +58,7 @@ function expressionHelper(
           categoryDisplay: [layer.categoryDisplay],
           legendDisplay: [layer.legendDisplay],
           legendPosition: [layer.legendPosition || 'right'],
-          emptySizeRatio: [layer.emptySizeRatio ?? EMPTY_SIZE_RATIOS.MEDIUM],
+          emptySizeRatio: [layer.emptySizeRatio ?? EMPTY_SIZE_RATIOS.SMALL],
           showValuesInLegend: [shouldShowValuesInLegend(layer, state.shape)],
           percentDecimals: [
             state.shape === 'waffle'
diff --git a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
index c9cbe63c98d8c..6910a3ea0966c 100644
--- a/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/toolbar.tsx
@@ -225,7 +225,7 @@ export function PieToolbar(props: VisualizationToolbarProps<PieVisualizationStat
               options={emptySizeRatioOptions}
               idSelected={
                 emptySizeRatioOptions.find(({ value }) => value === layer.emptySizeRatio)?.id ??
-                'emptySizeRatioOption-medium'
+                'emptySizeRatioOption-small'
               }
               onChange={onEmptySizeRatioChange}
               data-test-subj="lnsEmptySizeRatioButtonGroup"