mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] Save valuesInLegend:true
as legendStats:['value']
in preparation for legend statistics (#181953)
## Summary
To the code owners,
This PR updates the saved object of Lens with the following changes: the
property `valuesInLegend: boolean` is converted to the new property
`legendStats: ["currentAndLastValue"]` (cartesian) or `legendStats:
["value"]`(partition) to accommodate displaying additional legend
statistics in the future. There are no user-facing changes introduced. I
have updated all saved object shapes in the code to adhere to the new
structure. While the old structure will continue to function properly,
this update ensures cleaner code.
Fixes https://github.com/elastic/kibana/issues/181035 (phase 2). It's is
a continuation of https://github.com/elastic/kibana/pull/180917.
In comparison to the phase 1, we've removed the conversion of
legendStats to valuesInLegend which was initially added in the previous
PR to ensure backward compatibility for serverless applications.
<img width="807" alt="Screenshot 2024-04-25 at 10 51 50"
src="6c23d035
-f64d-4fb1-96c6-d30392ae6752">
I won't merge till the end of the week as it has to be released
separately from phase 1.
---------
Co-authored-by: Cauê Marcondes <55978943+cauemarcondes@users.noreply.github.com>
Co-authored-by: Alex Szabo <alex.szabo@elastic.co>
This commit is contained in:
parent
66ab2c3178
commit
ab065ad6da
26 changed files with 144 additions and 109 deletions
|
@ -14,9 +14,12 @@ import type {
|
|||
DatatableColumnMeta,
|
||||
ExpressionFunctionDefinition,
|
||||
} from '@kbn/expressions-plugin/common';
|
||||
import { LegendSize, XYLegendValue } from '@kbn/visualizations-plugin/common';
|
||||
import {
|
||||
LegendSize,
|
||||
ExpressionValueVisDimension,
|
||||
XYLegendValue,
|
||||
} from '@kbn/visualizations-plugin/common';
|
||||
import { EventAnnotationOutput } from '@kbn/event-annotation-plugin/common';
|
||||
import { ExpressionValueVisDimension } from '@kbn/visualizations-plugin/common';
|
||||
|
||||
import { MakeOverridesSerializable, Simplify } from '@kbn/chart-expressions-common/types';
|
||||
import {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,7 @@ import { cloneDeep } from 'lodash';
|
|||
import { PartitionLegendValue } from '@kbn/visualizations-plugin/common/constants';
|
||||
import { PieLayerState, PieVisualizationState } from '../../../common/types';
|
||||
|
||||
type PersistedPieLayerState = Omit<PieLayerState, 'legendStats'> & {
|
||||
type PersistedPieLayerState = PieLayerState & {
|
||||
showValuesInLegend?: boolean;
|
||||
};
|
||||
|
||||
|
@ -38,16 +38,3 @@ function convertToLegendStats(state: PieVisualizationState) {
|
|||
|
||||
return state;
|
||||
}
|
||||
|
||||
export function convertToPersistable(state: PieVisualizationState) {
|
||||
const newState = cloneDeep(state) as unknown as PersistedPieVisualizationState;
|
||||
|
||||
newState.layers.forEach((l) => {
|
||||
if ('legendStats' in l && Array.isArray(l.legendStats)) {
|
||||
l.showValuesInLegend = l.legendStats.includes(PartitionLegendValue.Value);
|
||||
delete l.legendStats;
|
||||
}
|
||||
});
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
|
|
@ -205,35 +205,6 @@ describe('pie_visualization', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#getPersistableState', () => {
|
||||
describe('converting to legend stats', () => {
|
||||
it('converts `legendStats` to `valuesInLegend`', () => {
|
||||
const runtimeState = getExampleState();
|
||||
// no legend stats at all
|
||||
const { state } = pieVisualization.getPersistableState!(runtimeState);
|
||||
expect('legendStats' in state.layers[0]).toBeFalsy();
|
||||
expect(state.layers[0].showValuesInLegend).toEqual(undefined);
|
||||
|
||||
// legend stats === ['value']
|
||||
runtimeState.layers[0].legendStats = [PartitionLegendValue.Value];
|
||||
const { state: stateWithShowValuesInLegendTrue } =
|
||||
pieVisualization.getPersistableState!(runtimeState);
|
||||
|
||||
expect('legendStats' in stateWithShowValuesInLegendTrue.layers[0]).toBeFalsy();
|
||||
expect(stateWithShowValuesInLegendTrue.layers[0].showValuesInLegend).toEqual(true);
|
||||
|
||||
// legend stats === ['value']
|
||||
runtimeState.layers[0].legendStats = [];
|
||||
|
||||
const { state: stateWithShowValuesInLegendFalse } =
|
||||
pieVisualization.getPersistableState!(runtimeState);
|
||||
|
||||
expect('legendStats' in stateWithShowValuesInLegendFalse.layers[0]).toBeFalsy();
|
||||
expect(stateWithShowValuesInLegendFalse.layers[0].showValuesInLegend).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeDimension', () => {
|
||||
it('removes corresponding collapse function if exists', () => {
|
||||
const state = getExampleState();
|
||||
|
|
|
@ -53,11 +53,7 @@ import { checkTableForContainsSmallValues } from './render_helpers';
|
|||
import { DatasourcePublicAPI } from '../..';
|
||||
import { nonNullable, getColorMappingDefaults } from '../../utils';
|
||||
import { getColorMappingTelemetryEvents } from '../../lens_ui_telemetry/color_telemetry_helpers';
|
||||
import {
|
||||
PersistedPieVisualizationState,
|
||||
convertToPersistable,
|
||||
convertToRuntime,
|
||||
} from './persistence';
|
||||
import { PersistedPieVisualizationState, convertToRuntime } from './persistence';
|
||||
|
||||
const metricLabel = i18n.translate('xpack.lens.pie.groupMetricLabelSingular', {
|
||||
defaultMessage: 'Metric',
|
||||
|
@ -183,10 +179,6 @@ export const getPieVisualization = ({
|
|||
};
|
||||
},
|
||||
|
||||
getPersistableState(state) {
|
||||
return { savedObjectReferences: [], state: convertToPersistable(state) };
|
||||
},
|
||||
|
||||
getMainPalette: (state) => {
|
||||
if (!state) {
|
||||
return undefined;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegendConfig } from '@kbn/visualizations-plugin/common';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { SavedObjectReference } from '@kbn/core/public';
|
||||
import { EVENT_ANNOTATION_GROUP_TYPE } from '@kbn/event-annotation-common';
|
||||
|
@ -83,7 +82,6 @@ export type XYPersistedLayerConfig =
|
|||
export type XYPersistedState = Omit<XYState, 'layers'> & {
|
||||
layers: XYPersistedLayerConfig[];
|
||||
valuesInLegend?: boolean;
|
||||
legend: Omit<LegendConfig, 'legendStats'>;
|
||||
};
|
||||
|
||||
export function convertToRuntime(
|
||||
|
@ -97,7 +95,7 @@ export function convertToRuntime(
|
|||
}
|
||||
|
||||
export function convertToPersistable(state: XYState) {
|
||||
const persistableState: XYPersistedState = convertToValuesInLegend(state);
|
||||
const persistableState: XYPersistedState = state;
|
||||
const savedObjectReferences: SavedObjectReference[] = [];
|
||||
const persistableLayers: XYPersistedLayerConfig[] = [];
|
||||
|
||||
|
@ -291,15 +289,3 @@ function convertToLegendStats(state: XYState & { valuesInLegend?: unknown }) {
|
|||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function convertToValuesInLegend(state: XYState) {
|
||||
const newState: XYPersistedState = cloneDeep(state);
|
||||
|
||||
if ('legendStats' in newState.legend && Array.isArray(newState.legend.legendStats)) {
|
||||
newState.valuesInLegend = newState.legend.legendStats.includes(
|
||||
XYLegendValue.CurrentAndLastValue
|
||||
);
|
||||
delete newState.legend.legendStats;
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
|
|
@ -3837,23 +3837,6 @@ describe('xy_visualization', () => {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should transform legendStats to valuesInLegend', () => {
|
||||
const state = exampleState();
|
||||
const { state: noLegendStatsState } = xyVisualization.getPersistableState!(state);
|
||||
expect(noLegendStatsState.legend.legendStats).not.toBeDefined();
|
||||
expect(noLegendStatsState.valuesInLegend).not.toBeDefined();
|
||||
|
||||
state.legend.legendStats = [XYLegendValue.CurrentAndLastValue];
|
||||
const { state: legendStatsState } = xyVisualization.getPersistableState!(state);
|
||||
expect(legendStatsState.legend.legendStats).not.toBeDefined();
|
||||
expect(legendStatsState.valuesInLegend).toEqual(true);
|
||||
|
||||
state.legend.legendStats = [];
|
||||
const { state: legendStatsStateFalsy } = xyVisualization.getPersistableState!(state);
|
||||
expect(legendStatsStateFalsy.legend.legendStats).not.toBeDefined();
|
||||
expect(legendStatsStateFalsy.valuesInLegend).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSupportedActionsForLayer', () => {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -112,6 +112,9 @@ Object {
|
|||
"layerId": "layer1",
|
||||
"layerType": "data",
|
||||
"legendDisplay": "hide",
|
||||
"legendStats": Array [
|
||||
"value",
|
||||
],
|
||||
"metrics": Array [
|
||||
"col2",
|
||||
],
|
||||
|
@ -120,7 +123,6 @@ Object {
|
|||
"primaryGroups": Array [
|
||||
"col1",
|
||||
],
|
||||
"showValuesInLegend": true,
|
||||
},
|
||||
],
|
||||
"shape": "pie",
|
||||
|
|
|
@ -112,7 +112,7 @@ const visConfig = {
|
|||
categoryDisplay: 'default',
|
||||
legendDisplay: 'hide',
|
||||
numberDisplay: 'percent',
|
||||
showValuesInLegend: true,
|
||||
legendStats: ['value'],
|
||||
nestedLegend: false,
|
||||
layerType: 'data',
|
||||
},
|
||||
|
|
|
@ -216,12 +216,14 @@ Object {
|
|||
"legend": Object {
|
||||
"isVisible": true,
|
||||
"legendSize": "xlarge",
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "bar_stacked",
|
||||
"title": "Empty XY chart",
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"yLeftExtent": Object {
|
||||
"mode": "full",
|
||||
},
|
||||
|
|
|
@ -168,12 +168,14 @@ Object {
|
|||
"legend": Object {
|
||||
"isVisible": true,
|
||||
"legendSize": "xlarge",
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "bar_stacked",
|
||||
"title": "Empty XY chart",
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"yLeftExtent": Object {
|
||||
"mode": "full",
|
||||
},
|
||||
|
@ -331,12 +333,14 @@ Object {
|
|||
"legend": Object {
|
||||
"isVisible": true,
|
||||
"legendSize": "xlarge",
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "bar_stacked",
|
||||
"title": "Empty XY chart",
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"yLeftExtent": Object {
|
||||
"mode": "full",
|
||||
},
|
||||
|
|
|
@ -158,12 +158,14 @@ Object {
|
|||
],
|
||||
"legend": Object {
|
||||
"isVisible": false,
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "bar_stacked",
|
||||
"title": "Empty XY chart",
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"yTitle": "",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -23,6 +23,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = (
|
|||
isVisible: true,
|
||||
position: 'right',
|
||||
legendSize: 'xlarge',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
preferredSeriesType: 'bar_stacked',
|
||||
|
@ -49,7 +50,6 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = (
|
|||
yLeft: false,
|
||||
yRight: true,
|
||||
},
|
||||
valuesInLegend: true,
|
||||
},
|
||||
query: {
|
||||
query: '',
|
||||
|
|
|
@ -24,6 +24,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = (
|
|||
legend: {
|
||||
isVisible: extraOptions?.showLegend,
|
||||
position: 'right',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
preferredSeriesType: 'bar_stacked',
|
||||
|
@ -39,7 +40,6 @@ export const getRulePreviewLensAttributes: GetLensAttributes = (
|
|||
splitAccessor: 'e92c8920-0449-4564-81f4-8945517817a4',
|
||||
},
|
||||
],
|
||||
valuesInLegend: true,
|
||||
yTitle: '',
|
||||
axisTitlesVisibilitySettings: {
|
||||
x: false,
|
||||
|
|
|
@ -492,7 +492,9 @@ describe('getEventsHistogramLensAttributes', () => {
|
|||
);
|
||||
|
||||
expect(result?.current?.state?.visualization).toEqual(
|
||||
expect.objectContaining({ valuesInLegend: true })
|
||||
expect.objectContaining({
|
||||
legend: expect.objectContaining({ legendStats: ['currentAndLastValue'] }),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = (
|
|||
isVisible: true,
|
||||
position: 'right',
|
||||
legendSize: 'xlarge',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
preferredSeriesType: 'bar_stacked',
|
||||
|
@ -50,7 +51,6 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = (
|
|||
yLeft: false,
|
||||
yRight: true,
|
||||
},
|
||||
valuesInLegend: true,
|
||||
},
|
||||
query: {
|
||||
query: '',
|
||||
|
|
|
@ -55,7 +55,9 @@ describe('getExternalAlertLensAttributes', () => {
|
|||
);
|
||||
|
||||
expect(result?.current?.state?.visualization).toEqual(
|
||||
expect.objectContaining({ valuesInLegend: true })
|
||||
expect.objectContaining({
|
||||
legend: expect.objectContaining({ legendStats: ['currentAndLastValue'] }),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,6 +22,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = (
|
|||
isVisible: true,
|
||||
position: 'right',
|
||||
legendSize: 'xlarge',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
preferredSeriesType: 'bar_stacked',
|
||||
|
@ -48,7 +49,6 @@ export const getExternalAlertLensAttributes: GetLensAttributes = (
|
|||
yLeft: false,
|
||||
yRight: true,
|
||||
},
|
||||
valuesInLegend: true,
|
||||
},
|
||||
query: {
|
||||
query: '',
|
||||
|
|
|
@ -232,6 +232,9 @@ Object {
|
|||
"legend": Object {
|
||||
"isVisible": true,
|
||||
"legendSize": "xlarge",
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "bar_stacked",
|
||||
|
@ -241,7 +244,6 @@ Object {
|
|||
"yRight": true,
|
||||
},
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"yLeftExtent": Object {
|
||||
"mode": "full",
|
||||
},
|
||||
|
|
|
@ -160,7 +160,9 @@ describe('getDnsTopDomainsLensAttributes', () => {
|
|||
|
||||
it('should render values in legend', () => {
|
||||
expect(result?.current?.state?.visualization).toEqual(
|
||||
expect.objectContaining({ valuesInLegend: true })
|
||||
expect.objectContaining({
|
||||
legend: expect.objectContaining({ legendStats: ['currentAndLastValue'] }),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,6 +22,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = (
|
|||
isVisible: true,
|
||||
position: 'right',
|
||||
legendSize: 'xlarge',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
fittingFunction: 'None',
|
||||
|
@ -36,7 +37,6 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = (
|
|||
yLeft: false,
|
||||
yRight: false,
|
||||
},
|
||||
valuesInLegend: true,
|
||||
tickLabelsVisibilitySettings: {
|
||||
x: true,
|
||||
yLeft: true,
|
||||
|
|
|
@ -194,6 +194,9 @@ Object {
|
|||
],
|
||||
"legend": Object {
|
||||
"isVisible": false,
|
||||
"legendStats": Array [
|
||||
"currentAndLastValue",
|
||||
],
|
||||
"position": "right",
|
||||
},
|
||||
"preferredSeriesType": "line",
|
||||
|
@ -204,7 +207,6 @@ Object {
|
|||
},
|
||||
"title": "Empty XY chart",
|
||||
"valueLabels": "hide",
|
||||
"valuesInLegend": true,
|
||||
"xTitle": "",
|
||||
"yLeftExtent": Object {
|
||||
"lowerBound": 0,
|
||||
|
|
|
@ -27,6 +27,7 @@ export const getRiskScoreOverTimeAreaAttributes: GetLensAttributes = (
|
|||
legend: {
|
||||
isVisible: false,
|
||||
position: 'right',
|
||||
legendStats: ['currentAndLastValue'],
|
||||
},
|
||||
valueLabels: 'hide',
|
||||
preferredSeriesType: 'line',
|
||||
|
@ -72,7 +73,6 @@ export const getRiskScoreOverTimeAreaAttributes: GetLensAttributes = (
|
|||
},
|
||||
yTitle: '',
|
||||
yRightTitle: '',
|
||||
valuesInLegend: true,
|
||||
labelsOrientation: {
|
||||
x: 0,
|
||||
yLeft: 0,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue