diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-sunburst-slice-clicks-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-sunburst-slice-clicks-visually-looks-correct-1-snap.png index 5acb1cdb20..6c21790f89 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-sunburst-slice-clicks-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-sunburst-slice-clicks-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mosaic-alpha-simple-mosaic-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mosaic-alpha-simple-mosaic-visually-looks-correct-1-snap.png index fde1ab8e8d..9bbaf20984 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mosaic-alpha-simple-mosaic-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mosaic-alpha-simple-mosaic-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-simple-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-simple-visually-looks-correct-1-snap.png index 6650404ffe..a21f0fa52a 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-simple-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-simple-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-test-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-test-visually-looks-correct-1-snap.png index f4b4694ce5..305ca0919e 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-test-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-waffle-alpha-test-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-show-tooltip-on-sunburst-1-snap.png b/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-show-tooltip-on-sunburst-1-snap.png index bdc9db8bf4..f102cfa5dc 100644 Binary files a/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-show-tooltip-on-sunburst-1-snap.png and b/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-show-tooltip-on-sunburst-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/waffle-stories-test-ts-waffle-should-render-cells-in-ascending-order-1-snap.png b/integration/tests/__image_snapshots__/waffle-stories-test-ts-waffle-should-render-cells-in-ascending-order-1-snap.png index efac3cf3ed..5e030c80b1 100644 Binary files a/integration/tests/__image_snapshots__/waffle-stories-test-ts-waffle-should-render-cells-in-ascending-order-1-snap.png and b/integration/tests/__image_snapshots__/waffle-stories-test-ts-waffle-should-render-cells-in-ascending-order-1-snap.png differ diff --git a/packages/charts/src/chart_types/partition_chart/layout/utils/legend_labels.ts b/packages/charts/src/chart_types/partition_chart/layout/utils/legend_labels.ts index 6400e1cb55..40b71cf9d3 100644 --- a/packages/charts/src/chart_types/partition_chart/layout/utils/legend_labels.ts +++ b/packages/charts/src/chart_types/partition_chart/layout/utils/legend_labels.ts @@ -7,6 +7,7 @@ */ import { LegendItemLabel } from '../../../../state/selectors/get_legend_items_labels'; +import { ValueFormatter } from '../../../../utils/common'; import { Layer } from '../../specs'; import { CHILDREN_KEY, @@ -15,15 +16,22 @@ import { PATH_KEY, ArrayNode, NULL_SMALL_MULTIPLES_KEY, + AGGREGATE_KEY, } from './group_by_rollup'; /** @internal */ -export function getLegendLabels(layers: Layer[], tree: HierarchyOfArrays, legendMaxDepth: number) { - return flatSlicesNames(layers, 0, tree).filter(({ depth }) => depth <= legendMaxDepth); +export function getLegendLabelsAndValue( + layers: Layer[], + tree: HierarchyOfArrays, + legendMaxDepth: number, + // if used the resulting label will be concatenated with the formatted value, use () => '' to avoid that + valueFormatter: ValueFormatter, +): LegendItemLabel[] { + return flatSlicesNames(layers, 0, tree, valueFormatter).filter(({ depth }) => depth <= legendMaxDepth); } /** @internal */ -export function getArrayNodeKey(arrayNode: ArrayNode): string { +function getArrayNodeKey(arrayNode: ArrayNode): string { return arrayNode[PATH_KEY].reduce((acc, { value, index }) => { if (value === HIERARCHY_ROOT_KEY || value === NULL_SMALL_MULTIPLES_KEY) return acc; return `${acc}(${index}):${value}__`; @@ -34,6 +42,7 @@ function flatSlicesNames( layers: Layer[], depth: number, tree: HierarchyOfArrays, + valueFormatter: ValueFormatter, keys: Map = new Map(), depths: Map = new Map(), ): LegendItemLabel[] { @@ -45,18 +54,20 @@ function flatSlicesNames( // format the key with the layer formatter const layer = layers[depth - 1]; const formatter = layer?.nodeLabel; - const formattedValue = formatter ? formatter(key) : `${key}`; + const formattedKey = formatter ? formatter(key) : `${key}`; // preventing errors from external formatters - if (formattedValue && formattedValue !== HIERARCHY_ROOT_KEY) { + if (formattedKey && formattedKey !== HIERARCHY_ROOT_KEY) { // Node key must be unique for each node in the tree const nodeKey = getArrayNodeKey(arrayNode); // save only the max depth, so we can compute the the max extension of the legend depths.set(nodeKey, depth); - keys.set(nodeKey, formattedValue); + + const formattedValue = valueFormatter(arrayNode[AGGREGATE_KEY]); + keys.set(nodeKey, `${formattedKey}${formattedValue}`); } const children = arrayNode[CHILDREN_KEY]; - flatSlicesNames(layers, depth + 1, children, keys, depths); + flatSlicesNames(layers, depth + 1, children, valueFormatter, keys, depths); } return [...depths.keys()].map((key) => ({ diff --git a/packages/charts/src/chart_types/partition_chart/state/chart_state.tsx b/packages/charts/src/chart_types/partition_chart/state/chart_state.tsx index 58fc675161..665b57f193 100644 --- a/packages/charts/src/chart_types/partition_chart/state/chart_state.tsx +++ b/packages/charts/src/chart_types/partition_chart/state/chart_state.tsx @@ -61,6 +61,8 @@ export class PartitionState implements InternalChartState { getLegendItemsLabels(globalState: GlobalChartState) { // order doesn't matter, but it needs to return the highest depth of the label occurrence so enough horizontal width is allocated + // the label item strings needs to be a concatenation of the label + the extra formatted value if available. + // this is required to compute the legend automatic width return getLegendItemsLabels(globalState); } diff --git a/packages/charts/src/chart_types/partition_chart/state/selectors/get_legend_items_labels.ts b/packages/charts/src/chart_types/partition_chart/state/selectors/get_legend_items_labels.ts index a9141948e6..0d1d8ab60e 100644 --- a/packages/charts/src/chart_types/partition_chart/state/selectors/get_legend_items_labels.ts +++ b/packages/charts/src/chart_types/partition_chart/state/selectors/get_legend_items_labels.ts @@ -9,15 +9,19 @@ import { createCustomCachedSelector } from '../../../../state/create_selector'; import { LegendItemLabel } from '../../../../state/selectors/get_legend_items_labels'; import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs'; -import { getLegendLabels } from '../../layout/utils/legend_labels'; +import { getLegendLabelsAndValue } from '../../layout/utils/legend_labels'; import { getPartitionSpecs } from './get_partition_specs'; import { getTrees } from './tree'; /** @internal */ export const getLegendItemsLabels = createCustomCachedSelector( [getPartitionSpecs, getSettingsSpecSelector, getTrees], - (specs, { legendMaxDepth, showLegend }, trees): LegendItemLabel[] => - specs.flatMap(({ layers }) => - showLegend ? trees.flatMap(({ tree }) => getLegendLabels(layers, tree, legendMaxDepth)) : [], + (specs, { legendMaxDepth, showLegend, showLegendExtra }, trees): LegendItemLabel[] => + specs.flatMap(({ layers, valueFormatter }) => + showLegend + ? trees.flatMap(({ tree }) => + getLegendLabelsAndValue(layers, tree, legendMaxDepth, showLegendExtra ? valueFormatter : () => ''), + ) + : [], ), ); diff --git a/storybook/stories/waffle/1_simple.story.tsx b/storybook/stories/waffle/1_simple.story.tsx index f82c3dfa55..4b0ae0afb7 100644 --- a/storybook/stories/waffle/1_simple.story.tsx +++ b/storybook/stories/waffle/1_simple.story.tsx @@ -22,13 +22,14 @@ import { mocks } from '@elastic/charts/src/mocks/hierarchical'; import { ArrayEntry } from '../../../packages/charts/src/chart_types/partition_chart/layout/utils/group_by_rollup'; import { useBaseTheme } from '../../use_base_theme'; -import { colorBrewerCategoricalStark9, discreteColor, productLookup } from '../utils/utils'; +import { colorBrewerCategoricalStark9, discreteColor } from '../utils/utils'; export const Example = () => { const showDebug = boolean('show table for debugging', false); const ascendingSort = boolean('ascending sort', false); // this is used to test the sorting capabilities const data = mocks.pie.slice(0, 4).sort(() => (Math.random() > 0.5 ? 1 : -1)); + const names: Record = { '7': 'Al', '3': 'Au', '5': 'Ag', '8': 'Cu' }; return ( { layers={[ { groupByRollup: (d: Datum) => d.sitc1, - nodeLabel: (d: Datum) => productLookup[d].name, + nodeLabel: (d: Datum) => names[d], shape: { fillColor: (d: ShapeTreeNode) => discreteColor(colorBrewerCategoricalStark9.slice(1))(d.sortIndex), },