Skip to content

Commit

Permalink
[Lens] support legendStats along with valuesInLegend in preparati…
Browse files Browse the repository at this point in the history
…on for legend statistics (#180917)

## Summary

This PR addresses phase one of
#181035.

Doesn't introduce any user facing changes. 
It starts supporting a new saved object property `legendStats` while
supporting a old `valuesInLegend` property. In this PR, `legendStats:
['values']` and `valuesInLegend:true` are treated as equal. When loading
the saved object, `valuesInLegend:true` is transformed to
`legendStats:['values']`. After loading the document, the Lens app logic
is built around the new `legendStats` property.
When user saves the saved object, we do a reverse operation- we save the
runtime state `legendStats:['values']` as `valuesInLegend: true` to
ensure backwards compatibility.


![image](https://github.com/elastic/kibana/assets/4283304/5e09b062-b4d3-424d-b8a8-79a08f4d6260)


Changes for runtime state:

- For xyCharts, the `valuesInLegend?: boolean ` property is replaced
with a more extensible `legend.legendStats?: LegendStats[]` interface

- For partition charts, the `showValuesInLegend?: boolean` property is
replaced with `legendStats?: LegendStats[]`.

after loading - in initialize function:

```ts
export function convertToRuntime(
  state: XYPersistedState,
  annotationGroups?: AnnotationGroups,
  references?: SavedObjectReference[]
) {
  const outputState = needsInjectReferences(state)
    ? injectReferences(state, annotationGroups, references)
    : state;
  if ('valuesInLegend' in outputState) {
    return convertToLegendStats(outputState);
  }
  return outputState;
}
```

before saving :

```ts
export function convertToPersistable(state: XYState) {
  const persistableState: XYPersistedState = convertToValuesInLegend(state);
  /.../
}
```

In the future the `legendStats` prop would contain also other types of
stats -see the [issue](#176583).
  • Loading branch information
mbondyra authored Apr 26, 2024
1 parent 7ad17c3 commit 52ca6ad
Show file tree
Hide file tree
Showing 54 changed files with 1,558 additions and 432 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
import type { DataView } from '@kbn/data-views-plugin/public';
import type { SavedObjectReference } from '@kbn/core/server';
import { AxesSettingsConfig } from '@kbn/visualizations-plugin/common';
import type { LegendStats } from '@kbn/visualizations-plugin/common/constants';
import type { Chart, ChartConfig, ChartLayer } from '../types';
import { DEFAULT_LAYER_ID } from '../utils';
import { XY_ID } from './constants';
Expand Down Expand Up @@ -130,6 +131,7 @@ export const getXYVisualizationState = (
isVisible: false,
position: 'right',
showSingleSeries: false,
legendStats: ['values' as LegendStats.values],
},
valueLabels: 'show',
yLeftScale: 'linear',
Expand All @@ -149,7 +151,6 @@ export const getXYVisualizationState = (
yRight: true,
},
preferredSeriesType: 'line',
valuesInLegend: false,
hideEndzones: true,
...custom,
});

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

Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export const strings = {
i18n.translate('expressionPartitionVis.reusable.function.args.truncateLegendHelpText', {
defaultMessage: 'Defines if the legend items will be truncated or not',
}),
getLegendStatsArgHelp: () =>
i18n.translate('expressionPartitionVis.reusable.function.args.legendStatsArgHelp', {
defaultMessage: 'Defines the legend stats',
}),
getMaxLegendLinesArgHelp: () =>
i18n.translate('expressionPartitionVis.reusable.function.args.maxLegendLinesHelpText', {
defaultMessage: 'Defines the number of lines per legend item',
Expand Down Expand Up @@ -97,10 +101,6 @@ export const strings = {
i18n.translate('expressionPartitionVis.reusable.function.args.labelsHelpText', {
defaultMessage: 'Pie labels config',
}),
getShowValuesInLegendArgHelp: () =>
i18n.translate('expressionPartitionVis.waffle.function.args.showValuesInLegendHelpText', {
defaultMessage: 'Show values in legend',
}),
getAriaLabelHelp: () =>
i18n.translate('expressionPartitionVis.reusable.functions.args.ariaLabelHelpText', {
defaultMessage: 'Specifies the aria label of the chart',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ValueFormats,
LegendDisplay,
} from '../types/expression_renderers';
import { ExpressionValueVisDimension } from '@kbn/visualizations-plugin/common';
import { ExpressionValueVisDimension, LegendStats } from '@kbn/visualizations-plugin/common';
import { Datatable } from '@kbn/expressions-plugin/common/expression_types/specs';
import { waffleVisFunction } from './waffle_vis_function';
import { PARTITION_LABELS_VALUE, PARTITION_VIS_RENDERER_NAME } from '../constants';
Expand All @@ -34,7 +34,7 @@ describe('interpreter/functions#waffleVis', () => {

const visConfig: WaffleVisConfig = {
addTooltip: true,
showValuesInLegend: true,
legendStats: [LegendStats.values],
metricsToLabels: JSON.stringify({}),
legendDisplay: LegendDisplay.SHOW,
legendPosition: 'right',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ export const waffleVisFunction = (): WaffleVisExpressionFunctionDefinition => ({
],
strict: true,
},
legendStats: {
types: ['string'],
multi: true,
help: strings.getLegendStatsArgHelp(),
},
truncateLegend: {
types: ['boolean'],
help: strings.getTruncateLegendArgHelp(),
Expand All @@ -104,11 +109,6 @@ export const waffleVisFunction = (): WaffleVisExpressionFunctionDefinition => ({
help: strings.getLabelsArgHelp(),
default: `{${PARTITION_LABELS_FUNCTION}}`,
},
showValuesInLegend: {
types: ['boolean'],
help: strings.getShowValuesInLegendArgHelp(),
default: false,
},
ariaLabel: {
types: ['string'],
help: strings.getAriaLabelHelp(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { AllowedChartOverrides, AllowedSettingsOverrides } from '@kbn/chart
import type { PaletteOutput } from '@kbn/coloring';
import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common';
import type { SerializedFieldFormat } from '@kbn/field-formats-plugin/common';
import type { ExpressionValueVisDimension } from '@kbn/visualizations-plugin/common';
import type { ExpressionValueVisDimension, LegendStats } from '@kbn/visualizations-plugin/common';
import type { LegendSize } from '@kbn/visualizations-plugin/public';
import {
type AllowedPartitionOverrides,
Expand Down Expand Up @@ -80,7 +80,7 @@ export interface PartitionVisParams extends VisCommonParams {
labels: LabelsParams;
palette: PaletteOutput;
isDonut?: boolean;
showValuesInLegend?: boolean;
legendStats?: LegendStats[];
respectSourceOrder?: boolean;
emptySizeRatio?: EmptySizeRatios;
startFromSecondLargestSlice?: boolean;
Expand Down Expand Up @@ -110,7 +110,7 @@ export interface MosaicVisConfig

export interface WaffleVisConfig extends Omit<VisCommonConfig, 'buckets'> {
bucket?: ExpressionValueVisDimension | string;
showValuesInLegend: boolean;
legendStats?: LegendStats[];
}

export interface PartitionChartProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { Position } from '@elastic/charts';
import { ArgTypes } from '@storybook/addons';
import { LegendStats } from '@kbn/visualizations-plugin/common/constants';
import { EmptySizeRatios, LegendDisplay } from '../../../common';
import { ChartTypes } from '../../../common/types';

Expand Down Expand Up @@ -206,11 +207,12 @@ export const waffleArgTypes: ArgTypes = {
control: { type: 'text', disable: true },
},
...argTypes,
showValuesInLegend: {
name: `${visConfigName}.nestedLegend`,
description: 'Enable displaying values in the legend',
type: { name: 'boolean', required: false },
table: { type: { summary: 'boolean' }, defaultValue: { summary: false } },
control: { type: 'boolean' },
legendStats: {
name: `${visConfigName}.legendStats`,
description: 'Legend stats',
type: { name: 'string', required: false },
table: { type: { summary: 'string' }, defaultValue: { summary: undefined } },
options: [LegendStats.values],
control: { type: 'select' },
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,4 @@ export const waffleConfig: PartitionVisParams = {
},
],
},
showValuesInLegend: false,
};

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

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
} from '@kbn/expressions-plugin/public';
import type { FieldFormat } from '@kbn/field-formats-plugin/common';
import { getOverridesFor } from '@kbn/chart-expressions-common';
import { LegendStats } from '@kbn/visualizations-plugin/common/constants';
import { consolidateMetricColumns } from '../../common/utils';
import { DEFAULT_PERCENT_DECIMALS } from '../../common/constants';
import {
Expand Down Expand Up @@ -563,7 +564,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => {
legendColorPicker={props.uiState ? LegendColorPickerWrapper : undefined}
flatLegend={flatLegend}
legendSort={customLegendSort}
showLegendExtra={visParams.showValuesInLegend}
showLegendExtra={visParams.legendStats?.[0] === LegendStats.values}
onElementClick={([elementEvent]) => {
// this cast is safe because we are rendering a partition chart
const [layerValues] = elementEvent as PartitionElementEvent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { Datatable } from '@kbn/expressions-plugin/public';
import { LegendStats } from '@kbn/visualizations-plugin/common/constants';
import {
BucketColumns,
PartitionVisParams,
Expand Down Expand Up @@ -381,6 +382,6 @@ export const createMockWaffleParams = (): PartitionVisParams => {
},
],
},
showValuesInLegend: true,
legendStats: [LegendStats.values],
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export const createArgsWithLayers = (
position: Position.Top,
},
valueLabels: 'hide',
valuesInLegend: false,
xAxisConfig: {
type: 'xAxisConfig',
position: 'bottom',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ export const commonXYArgs: CommonXYFn['args'] = {
default: false,
help: strings.getHideEndzonesHelp(),
},
valuesInLegend: {
types: ['boolean'],
default: false,
help: strings.getValuesInLegendHelp(),
},
ariaLabel: {
types: ['string'],
help: strings.getAriaLabelHelp(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ export const legendConfigFunction: LegendConfigFn = {
],
strict: true,
},
legendStats: {
types: ['string'],
multi: true,
help: i18n.translate('expressionXY.legendConfig.legendStats.help', {
defaultMessage: 'Specifies the legend stats.',
}),
},
},
async fn(input, args, handlers) {
const { legendConfigFn } = await import('./legend_config_fn');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ export const strings = {
i18n.translate('expressionXY.xyVis.hideEndzones.help', {
defaultMessage: 'Hide endzone markers for partial data',
}),
getValuesInLegendHelp: () =>
i18n.translate('expressionXY.xyVis.valuesInLegend.help', {
defaultMessage: 'Show values in legend',
getLegendStatsArgHelp: () =>
i18n.translate('expressionXY.xyVis.legendStats.help', {
defaultMessage: 'Define the stats to show in the legend',
}),
getAriaLabelHelp: () =>
i18n.translate('expressionXY.xyVis.ariaLabel.help', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
DatatableColumnMeta,
ExpressionFunctionDefinition,
} from '@kbn/expressions-plugin/common';
import { LegendSize } from '@kbn/visualizations-plugin/common';
import { LegendSize, LegendStats } from '@kbn/visualizations-plugin/common';
import { EventAnnotationOutput } from '@kbn/event-annotation-plugin/common';
import { ExpressionValueVisDimension } from '@kbn/visualizations-plugin/common';

Expand Down Expand Up @@ -214,6 +214,10 @@ export interface LegendConfig {
* Limited to max of 70% of the chart container dimension Vertical legends limited to min of 30% of computed width
*/
legendSize?: LegendSize;
/**
* metrics to display in the legend
*/
legendStats?: LegendStats[];
}

// Arguments to XY chart expression, with computed properties
Expand All @@ -226,7 +230,6 @@ export interface XYArgs extends DataLayerArgs {
fittingFunction?: FittingFunction;
fillOpacity?: number;
hideEndzones?: boolean;
valuesInLegend?: boolean;
ariaLabel?: string;
yAxisConfigs?: YAxisConfigResult[];
xAxisConfig?: XAxisConfigResult;
Expand Down Expand Up @@ -277,7 +280,6 @@ export interface LayeredXYArgs {
fittingFunction?: FittingFunction;
fillOpacity?: number;
hideEndzones?: boolean;
valuesInLegend?: boolean;
ariaLabel?: string;
yAxisConfigs?: YAxisConfigResult[];
xAxisConfig?: XAxisConfigResult;
Expand All @@ -302,7 +304,6 @@ export interface XYProps {
fittingFunction?: FittingFunction;
fillOpacity?: number;
hideEndzones?: boolean;
valuesInLegend?: boolean;
ariaLabel?: string;
yAxisConfigs?: YAxisConfigResult[];
xAxisConfig?: XAxisConfigResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import { XYChart, XYChartRenderProps } from './xy_chart';
import { ExtendedDataLayerConfig, XYProps, AnnotationLayerConfigResult } from '../../common/types';
import { DataLayers } from './data_layers';
import { SplitChart } from './split_chart';
import { LegendSize } from '@kbn/visualizations-plugin/common';
import { LegendSize, LegendStats } from '@kbn/visualizations-plugin/common';
import type { LayerCellValueActions } from '../types';

const onClickValue = jest.fn();
Expand Down Expand Up @@ -740,7 +740,10 @@ describe('XYChart component', () => {
test('ignores legend extra for ordinal chart', () => {
const { args } = sampleArgs();
const component = shallow(
<XYChart {...defaultProps} args={{ ...args, valuesInLegend: true }} />
<XYChart
{...defaultProps}
args={{ ...args, legend: { ...args.legend, legendStats: [LegendStats.values] } }}
/>
);
expect(component.find(Settings).at(0).prop('showLegendExtra')).toEqual(false);
});
Expand All @@ -752,8 +755,11 @@ describe('XYChart component', () => {
{...defaultProps}
args={{
...args,
legend: {
...args.legend,
legendStats: [LegendStats.values],
},
layers: [dateHistogramLayer],
valuesInLegend: true,
}}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
import {
DEFAULT_LEGEND_SIZE,
LegendSizeToPixels,
LegendStats,
} from '@kbn/visualizations-plugin/common/constants';
import { PersistedState } from '@kbn/visualizations-plugin/public';
import { getOverridesFor, ChartSizeSpec } from '@kbn/chart-expressions-common';
Expand Down Expand Up @@ -220,7 +221,6 @@ export function XYChart({
emphasizeFitting,
valueLabels,
hideEndzones,
valuesInLegend,
yAxisConfigs,
xAxisConfig,
splitColumnAccessor,
Expand Down Expand Up @@ -869,7 +869,7 @@ export function XYChart({
)
: undefined
}
showLegendExtra={isHistogramViz && valuesInLegend}
showLegendExtra={isHistogramViz && legend.legendStats?.[0] === LegendStats.values}
ariaLabel={args.ariaLabel}
ariaUseDefaultSummary={!args.ariaLabel}
orderOrdinalBinsBy={
Expand Down
Loading

0 comments on commit 52ca6ad

Please sign in to comment.