[Lens] Introduce separate dimension groups for mosaic rows and columns (#139214)

* [Lens] Introduce separate dimension groups for mosaic rows and columns

* swap labels

* fix nits

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Joe Reuter <johannes.reuter@elastic.co>
This commit is contained in:
Alexey Antonov 2022-09-07 22:55:12 +03:00 committed by GitHub
parent c771828242
commit 6ed79f42db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 297 additions and 70 deletions

View file

@ -311,7 +311,7 @@ function getLensAttributesPartition(
const pieConfig: PieVisualizationState = {
layers: [
{
groups: ['col1'],
primaryGroups: ['col1'],
metric: 'col2',
layerId: 'layer1',
layerType: 'data',

View file

@ -10,6 +10,7 @@
export * from './constants';
export * from './types';
export * from './visualizations';
// Note: do not import the expression folder here or the page bundle will be bloated with all
// the package

View file

@ -63,7 +63,8 @@ export enum EmptySizeRatios {
}
export interface SharedPieLayerState {
groups: string[];
primaryGroups: string[];
secondaryGroups?: string[];
metric?: string;
numberDisplay: NumberDisplayType;
categoryDisplay: CategoryDisplayType;

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export { isPartitionShape } from './partition/utils';

View file

@ -0,0 +1,11 @@
/*
* 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 type { PieChartType } from '../../types';
export const isPartitionShape = (shape: PieChartType | string) =>
['donut', 'pie', 'treemap', 'mosaic', 'waffle'].includes(shape);

View file

@ -30,7 +30,6 @@ interface PartitionChartMeta {
groupLabel: string;
maxBuckets: number;
isExperimental?: boolean;
requiredMinDimensionCount?: number;
toolbarPopover: {
isDisabled?: boolean;
categoryOptions: Array<{
@ -202,7 +201,6 @@ export const PartitionChartsMeta: Record<PieChartType, PartitionChartMeta> = {
legend: {
getShowLegendDefault: () => false,
},
requiredMinDimensionCount: 2,
},
waffle: {
icon: IconChartWaffle,

View file

@ -9,9 +9,6 @@ import type { Datatable } from '@kbn/expressions-plugin/public';
import type { PieChartType, PieLayerState } from '../../../common/types';
import { PartitionChartsMeta } from './partition_charts_meta';
export const isPartitionShape = (shape: PieChartType | string) =>
['donut', 'pie', 'treemap', 'mosaic', 'waffle'].includes(shape);
export const shouldShowValuesInLegend = (layer: PieLayerState, shape: PieChartType) => {
if ('showValues' in PartitionChartsMeta[shape]?.legend) {
return layer.showValuesInLegend ?? PartitionChartsMeta[shape]?.legend?.showValues ?? true;

View file

@ -65,7 +65,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: [],
primaryGroups: [],
metric: 'a',
numberDisplay: NumberDisplay.HIDDEN,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -555,7 +555,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a'],
primaryGroups: ['a'],
metric: 'b',
numberDisplay: NumberDisplay.HIDDEN,
@ -579,9 +579,8 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a'],
primaryGroups: ['a'],
metric: 'b',
numberDisplay: NumberDisplay.HIDDEN,
categoryDisplay: CategoryDisplay.INSIDE,
legendDisplay: 'show',
@ -613,7 +612,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: [],
primaryGroups: [],
metric: 'a',
numberDisplay: NumberDisplay.HIDDEN,
@ -663,7 +662,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a', 'b'],
primaryGroups: ['a', 'b'],
metric: 'e',
numberDisplay: NumberDisplay.VALUE,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -712,7 +711,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a', 'b'],
primaryGroups: ['a', 'b'],
metric: 'e',
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -749,7 +748,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a'],
primaryGroups: ['a'],
metric: 'b',
numberDisplay: NumberDisplay.HIDDEN,
@ -772,7 +771,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a'],
primaryGroups: ['a'],
metric: 'b',
numberDisplay: NumberDisplay.HIDDEN,
@ -806,7 +805,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: [],
primaryGroups: [],
metric: 'a',
numberDisplay: NumberDisplay.HIDDEN,
@ -848,7 +847,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a', 'b'],
primaryGroups: ['a', 'b'],
metric: 'c',
numberDisplay: NumberDisplay.HIDDEN,
@ -883,7 +882,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: [],
primaryGroups: [],
metric: 'a',
numberDisplay: NumberDisplay.HIDDEN,
@ -921,7 +920,7 @@ describe('suggestions', () => {
{
layerId: 'first',
layerType: layerTypes.DATA,
groups: ['a', 'b'],
primaryGroups: ['a', 'b'],
metric: 'c',
numberDisplay: NumberDisplay.HIDDEN,
categoryDisplay: CategoryDisplay.INSIDE,

View file

@ -19,10 +19,10 @@ import {
NumberDisplay,
PieChartTypes,
PieVisualizationState,
isPartitionShape,
} from '../../../common';
import type { PieChartType } from '../../../common/types';
import { PartitionChartsMeta } from './partition_charts_meta';
import { isPartitionShape } from './render_helpers';
function hasIntervalScale(columns: TableSuggestionColumn[]) {
return columns.some((col) => col.operation.scale === 'interval');
@ -131,13 +131,13 @@ export function suggestions({
? {
...state.layers[0],
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
layerType: layerTypes.DATA,
}
: {
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -196,7 +196,7 @@ export function suggestions({
? {
...state.layers[0],
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
categoryDisplay:
state.layers[0].categoryDisplay === CategoryDisplay.INSIDE
@ -206,7 +206,7 @@ export function suggestions({
}
: {
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -243,14 +243,16 @@ export function suggestions({
? {
...state.layers[0],
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups[0] ? [groups[0].columnId] : [],
secondaryGroups: groups[1] ? [groups[1].columnId] : [],
metric: metricColumnId,
categoryDisplay: CategoryDisplay.DEFAULT,
layerType: layerTypes.DATA,
}
: {
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups[0] ? [groups[0].columnId] : [],
secondaryGroups: groups[1] ? [groups[1].columnId] : [],
metric: metricColumnId,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -282,14 +284,14 @@ export function suggestions({
? {
...state.layers[0],
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
categoryDisplay: CategoryDisplay.DEFAULT,
layerType: layerTypes.DATA,
}
: {
layerId: table.layerId,
groups: groups.map((col) => col.columnId),
primaryGroups: groups.map((col) => col.columnId),
metric: metricColumnId,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,

View file

@ -61,14 +61,16 @@ type GenerateLabelsAstArguments = (
export const getSortedGroups = (
datasource: DatasourcePublicAPI | undefined,
layer: PieLayerState
layer: PieLayerState,
accessor: 'primaryGroups' | 'secondaryGroups' = 'primaryGroups'
) => {
const originalOrder = datasource
?.getTableSpec()
.map(({ columnId }: { columnId: string }) => columnId)
.filter((columnId: string) => layer.groups.includes(columnId));
.filter((columnId: string) => layer[accessor]?.includes(columnId));
// When we add a column it could be empty, and therefore have no order
return Array.from(new Set(originalOrder?.concat(layer.groups)));
return Array.from(new Set(originalOrder?.concat(layer[accessor] ?? [])));
};
const prepareDimension = (accessor: string) => {
@ -262,7 +264,15 @@ function expressionHelper(
): Ast | null {
const layer = state.layers[0];
const datasource = datasourceLayers[layer.layerId];
const groups = getSortedGroups(datasource, layer);
const groups = Array.from(
new Set(
[
getSortedGroups(datasource, layer, 'primaryGroups'),
layer.secondaryGroups ? getSortedGroups(datasource, layer, 'secondaryGroups') : [],
].flat()
)
);
const operations = groups
.map((columnId) => ({

View file

@ -306,7 +306,7 @@ export function DimensionEditor(
paletteService: PaletteRegistry;
}
) {
if (props.accessor !== Object.values(props.state.layers)[0].groups[0]) return null;
if (props.accessor !== Object.values(props.state.layers)[0].primaryGroups[0]) return null;
return (
<PalettePicker
palettes={props.paletteService}

View file

@ -35,7 +35,7 @@ function getExampleState(): PieVisualizationState {
{
layerId: LAYER_ID,
layerType: layerTypes.DATA,
groups: [],
primaryGroups: [],
metric: undefined,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -84,7 +84,7 @@ describe('pie_visualization', () => {
const prevState: PieVisualizationState = {
layers: [
{
groups: ['a'],
primaryGroups: ['a'],
layerId: LAYER_ID,
layerType: layerTypes.DATA,
numberDisplay: NumberDisplay.PERCENT,

View file

@ -30,7 +30,8 @@ import { PieChartTypes, PieLayerState, PieVisualizationState } from '../../../co
function newLayerState(layerId: string): PieLayerState {
return {
layerId,
groups: [],
primaryGroups: [],
secondaryGroups: undefined,
metric: undefined,
numberDisplay: NumberDisplay.PERCENT,
categoryDisplay: CategoryDisplay.DEFAULT,
@ -122,21 +123,22 @@ export const getPieVisualization = ({
}
const datasource = frame.datasourceLayers[layer.layerId];
const originalOrder = getSortedGroups(datasource, layer);
// When we add a column it could be empty, and therefore have no order
const sortedColumns: AccessorConfig[] = originalOrder.map((accessor) => ({
columnId: accessor,
}));
if (sortedColumns.length) {
applyPaletteToColumnConfig(sortedColumns, state, paletteService);
}
const getPrimaryGroupConfig = (): VisualizationDimensionGroupConfig => {
const originalOrder = getSortedGroups(datasource, layer);
// When we add a column it could be empty, and therefore have no order
const accessors: AccessorConfig[] = originalOrder.map((accessor) => ({
columnId: accessor,
}));
const getSliceByGroup = (): VisualizationDimensionGroupConfig => {
const baseProps = {
if (accessors.length) {
applyPaletteToColumnConfig(accessors, state, paletteService);
}
const primaryGroupConfigBaseProps = {
required: true,
groupId: 'groups',
accessors: sortedColumns,
groupId: 'primaryGroups',
accessors,
enableDimensionEditor: true,
filterOperations: bucketedOperations,
};
@ -145,33 +147,79 @@ export const getPieVisualization = ({
case 'donut':
case 'pie':
return {
...baseProps,
...primaryGroupConfigBaseProps,
groupLabel: i18n.translate('xpack.lens.pie.sliceGroupLabel', {
defaultMessage: 'Slice by',
}),
dimensionEditorGroupLabel: i18n.translate('xpack.lens.pie.sliceDimensionGroupLabel', {
defaultMessage: 'Slice',
}),
supportsMoreColumns: sortedColumns.length < PartitionChartsMeta.pie.maxBuckets,
supportsMoreColumns: accessors.length < PartitionChartsMeta.pie.maxBuckets,
dataTestSubj: 'lnsPie_sliceByDimensionPanel',
};
case 'mosaic':
return {
...primaryGroupConfigBaseProps,
groupLabel: i18n.translate('xpack.lens.pie.verticalAxisLabel', {
defaultMessage: 'Vertical axis',
}),
dimensionEditorGroupLabel: i18n.translate('xpack.lens.pie.verticalAxisDimensionLabel', {
defaultMessage: 'Vertical axis',
}),
supportsMoreColumns: accessors.length === 0,
dataTestSubj: 'lnsPie_verticalAxisDimensionPanel',
};
default:
return {
...baseProps,
...primaryGroupConfigBaseProps,
groupLabel: i18n.translate('xpack.lens.pie.treemapGroupLabel', {
defaultMessage: 'Group by',
}),
dimensionEditorGroupLabel: i18n.translate('xpack.lens.pie.treemapDimensionGroupLabel', {
defaultMessage: 'Group',
}),
supportsMoreColumns: sortedColumns.length < PartitionChartsMeta[state.shape].maxBuckets,
supportsMoreColumns: accessors.length < PartitionChartsMeta[state.shape].maxBuckets,
dataTestSubj: 'lnsPie_groupByDimensionPanel',
requiredMinDimensionCount: PartitionChartsMeta[state.shape].requiredMinDimensionCount,
};
}
};
const getMetricGroup = (): VisualizationDimensionGroupConfig => ({
const getSecondaryGroupConfig = (): VisualizationDimensionGroupConfig | undefined => {
const originalSecondaryOrder = getSortedGroups(datasource, layer, 'secondaryGroups');
const accessors = originalSecondaryOrder.map((accessor) => ({
columnId: accessor,
}));
const secondaryGroupConfigBaseProps = {
required: true,
groupId: 'secondaryGroups',
accessors,
enableDimensionEditor: true,
filterOperations: bucketedOperations,
};
switch (state.shape) {
case 'mosaic':
return {
...secondaryGroupConfigBaseProps,
groupLabel: i18n.translate('xpack.lens.pie.horizontalAxisLabel', {
defaultMessage: 'Horizontal axis',
}),
dimensionEditorGroupLabel: i18n.translate(
'xpack.lens.pie.horizontalAxisDimensionLabel',
{
defaultMessage: 'Horizontal axis',
}
),
supportsMoreColumns: accessors.length === 0,
dataTestSubj: 'lnsPie_horizontalAxisDimensionPanel',
};
default:
return undefined;
}
};
const getMetricGroupConfig = (): VisualizationDimensionGroupConfig => ({
groupId: 'metric',
groupLabel: i18n.translate('xpack.lens.pie.groupsizeLabel', {
defaultMessage: 'Size by',
@ -192,7 +240,9 @@ export const getPieVisualization = ({
});
return {
groups: [getSliceByGroup(), getMetricGroup()],
groups: [getPrimaryGroupConfig(), getSecondaryGroupConfig(), getMetricGroupConfig()].filter(
Boolean
) as VisualizationDimensionGroupConfig[],
};
},
@ -203,8 +253,20 @@ export const getPieVisualization = ({
if (l.layerId !== layerId) {
return l;
}
if (groupId === 'groups') {
return { ...l, groups: [...l.groups.filter((group) => group !== columnId), columnId] };
if (groupId === 'primaryGroups') {
return {
...l,
primaryGroups: [...l.primaryGroups.filter((group) => group !== columnId), columnId],
};
}
if (groupId === 'secondaryGroups') {
return {
...l,
secondaryGroups: [
...(l.secondaryGroups?.filter((group) => group !== columnId) || []),
columnId,
],
};
}
return { ...l, metric: columnId };
}),
@ -221,7 +283,11 @@ export const getPieVisualization = ({
if (l.metric === columnId) {
return { ...l, metric: undefined };
}
return { ...l, groups: l.groups.filter((c) => c !== columnId) };
return {
...l,
primaryGroups: l.primaryGroups.filter((c) => c !== columnId),
secondaryGroups: l.secondaryGroups?.filter((c) => c !== columnId) ?? undefined,
};
}),
};
},
@ -288,7 +354,7 @@ export const getPieVisualization = ({
if (
numericColumn &&
state.shape === 'waffle' &&
layer.groups.length &&
layer.primaryGroups.length &&
checkTableForContainsSmallValues(frame.activeData[layerId], numericColumn.id, 1)
) {
warningMessages.push(

View file

@ -29,6 +29,7 @@ import {
getLensFilterMigrations,
getLensDataViewMigrations,
commonMigrateMetricIds,
commonMigratePartitionChartGroups,
} from '../migrations/common_migrations';
import {
CustomVisualizationMigrations,
@ -134,7 +135,13 @@ export const makeLensEmbeddableFactory =
},
'8.5.0': (state) => {
const lensState = state as unknown as { attributes: LensDocShape840<VisState840> };
const migratedLensState = commonMigrateMetricIds(lensState.attributes);
let migratedLensState = commonMigrateMetricIds(lensState.attributes);
migratedLensState = commonMigratePartitionChartGroups(
migratedLensState as LensDocShape840<{
shape: string;
layers: Array<{ groups?: string[] }>;
}>
);
return {
...lensState,
attributes: migratedLensState,

View file

@ -7,7 +7,12 @@
import { DataViewSpec } from '@kbn/data-views-plugin/common';
import { Filter } from '@kbn/es-query';
import { getLensDataViewMigrations, getLensFilterMigrations } from './common_migrations';
import {
getLensDataViewMigrations,
getLensFilterMigrations,
commonMigratePartitionChartGroups,
} from './common_migrations';
import { LensDocShape840 } from '..';
describe('Lens migrations', () => {
describe('applying filter migrations', () => {
@ -106,4 +111,62 @@ describe('Lens migrations', () => {
});
});
});
describe('migrate partition chart "groups" to new shape', () => {
['donut', 'pie', 'treemap', 'mosaic', 'waffle'].forEach((chartType: string) => {
it(`should migrate "group" to "primaryGroups" for "${chartType}" chart`, () => {
const lensVisualizationSavedObject = {
attributes: {
state: {
visualization: {
shape: chartType,
layers: [{ groups: ['a'] }],
},
},
} as LensDocShape840<{
shape: string;
layers: Array<{ groups?: string[] }>;
}>,
};
const migratedVisualization = commonMigratePartitionChartGroups(
lensVisualizationSavedObject.attributes
).state.visualization;
expect(migratedVisualization.layers[0]).not.toHaveProperty('groups');
expect(migratedVisualization.layers[0]).toHaveProperty('primaryGroups', ['a']);
});
});
it(`should migrate "group" to "primaryGroups" and "secondaryGroups" for mosaic`, () => {
const lensVisualizationSavedObject = {
attributes: {
state: {
visualization: {
shape: 'mosaic',
layers: [{ groups: ['a', 'b'] }],
},
},
} as LensDocShape840<{
shape: string;
layers: Array<{ groups?: string[] }>;
}>,
};
const migratedVisualization = commonMigratePartitionChartGroups(
lensVisualizationSavedObject.attributes
).state.visualization;
expect(migratedVisualization.layers[0]).toMatchInlineSnapshot(`
Object {
"primaryGroups": Array [
"a",
],
"secondaryGroups": Array [
"b",
],
}
`);
});
});
});

View file

@ -31,8 +31,9 @@ import {
LensDocShape830,
VisStatePre830,
LensDocShape840,
LensDocShape850,
} from './types';
import { DOCUMENT_FIELD_NAME, layerTypes, LegacyMetricState } from '../../common';
import { DOCUMENT_FIELD_NAME, layerTypes, LegacyMetricState, isPartitionShape } from '../../common';
import { LensDocShape } from './saved_object_migrations';
export const commonRenameOperationsForFormula = (
@ -438,3 +439,51 @@ export const commonMigrateMetricIds = (
return newAttributes;
};
export const commonMigratePartitionChartGroups = (
attributes: LensDocShape840<{
shape: string;
layers: Array<{ groups?: string[] }>;
}>
): LensDocShape850<{
shape: string;
layers: Array<{ primaryGroups?: string[]; secondaryGroups?: string[] }>;
}> => {
if (
attributes.state.visualization?.layers &&
isPartitionShape(attributes.state.visualization.shape)
) {
return {
...attributes,
state: {
...attributes.state,
visualization: {
...attributes.state.visualization,
layers: attributes.state.visualization.layers.map((l) => {
const groups = l.groups;
if (groups) {
delete l.groups;
if (attributes.state.visualization.shape === 'mosaic') {
return {
...l,
primaryGroups: [groups[0]],
secondaryGroups: groups.length === 2 ? [groups[1]] : undefined,
};
}
return {
...l,
primaryGroups: groups,
};
}
return l;
}),
},
},
};
}
return attributes as LensDocShape850<{
shape: string;
layers: Array<{ primaryGroups?: string[]; secondaryGroups?: string[] }>;
}>;
};

View file

@ -54,6 +54,7 @@ import {
commonPreserveOldLegendSizeDefault,
getLensDataViewMigrations,
commonMigrateMetricIds,
commonMigratePartitionChartGroups,
} from './common_migrations';
interface LensDocShapePre710<VisualizationState = unknown> {
@ -520,6 +521,18 @@ const migrateMetricIds: SavedObjectMigrationFn<LensDocShape840, LensDocShape840>
attributes: commonMigrateMetricIds(doc.attributes),
});
const migratePartitionChartGroups: SavedObjectMigrationFn<LensDocShape840, LensDocShape840> = (
doc
) => ({
...doc,
attributes: commonMigratePartitionChartGroups(
doc.attributes as LensDocShape840<{
shape: string;
layers: Array<{ groups?: string[] }>;
}>
),
});
const lensMigrations: SavedObjectMigrationMap = {
'7.7.0': removeInvalidAccessors,
// The order of these migrations matter, since the timefield migration relies on the aggConfigs
@ -540,7 +553,7 @@ const lensMigrations: SavedObjectMigrationMap = {
enhanceTableRowHeight
),
'8.3.0': flow(lockOldMetricVisSettings, preserveOldLegendSizeDefault, fixValueLabelsInXY),
'8.5.0': flow(migrateMetricIds),
'8.5.0': flow(migrateMetricIds, migratePartitionChartGroups),
};
export const getAllMigrations = (

View file

@ -272,3 +272,5 @@ export type VisState830 = XYVisualizationState830;
export type VisState840 = VisState830;
export type LensDocShape840<VisualizationState = unknown> = LensDocShape830<VisualizationState>;
export type LensDocShape850<VisualizationState = unknown> = LensDocShape840<VisualizationState>;

View file

@ -138,7 +138,7 @@ function getLensAttributes(
layerId: 'layer1',
metric: 'ed999e9d-204c-465b-897f-fe1a125b39ed',
numberDisplay: 'percent',
groups: ['8690befd-fd69-4246-af4a-dd485d2a3b38'],
primaryGroups: ['8690befd-fd69-4246-af4a-dd485d2a3b38'],
categoryDisplay: 'default',
},
],

View file

@ -116,7 +116,7 @@ function getLensAttributes(
layerId: 'layer1',
metric: 'ed999e9d-204c-465b-897f-fe1a125b39ed',
numberDisplay: 'percent',
groups: ['8690befd-fd69-4246-af4a-dd485d2a3b38'],
primaryGroups: ['8690befd-fd69-4246-af4a-dd485d2a3b38'],
categoryDisplay: 'default',
},
],

View file

@ -103,15 +103,15 @@ Object {
"layers": Array [
Object {
"categoryDisplay": "default",
"groups": Array [
"col1",
],
"layerId": "layer1",
"layerType": "data",
"legendDisplay": "hide",
"metric": "col2",
"nestedLegend": false,
"numberDisplay": "percent",
"primaryGroups": Array [
"col1",
],
"showValuesInLegend": true,
},
],

View file

@ -100,7 +100,7 @@ const visConfig: PieVisualizationState = {
layers: [
{
layerId: 'layer1',
groups: ['col1'],
primaryGroups: ['col1'],
metric: 'col2',
categoryDisplay: 'default',
legendDisplay: 'hide',