[Lens] PartitionVis expression types improvement. (#144248)

* Partition labels added.

* Theme function added.

* Added partitionVis types safety.

* Fixed visdimension generation.

* Update x-pack/plugins/lens/public/visualizations/partition/to_expression.ts

Co-authored-by: Andrew Tate <drewctate@gmail.com>

* Update x-pack/plugins/lens/public/visualizations/partition/to_expression.ts

Co-authored-by: Andrew Tate <drewctate@gmail.com>

* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'

* Fixed types.

Co-authored-by: Andrew Tate <drewctate@gmail.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Yaroslav Kuznietsov 2022-11-03 20:20:41 +02:00 committed by GitHub
parent 1855f2207d
commit f065d66bb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 144 deletions

View file

@ -31,6 +31,7 @@ export type {
TreemapVisExpressionFunctionDefinition,
MosaicVisExpressionFunctionDefinition,
WaffleVisExpressionFunctionDefinition,
PartitionLabelsExpressionFunctionDefinition,
} from './types/expression_functions';
export type {

View file

@ -18,6 +18,7 @@ import {
TREEMAP_VIS_EXPRESSION_NAME,
MOSAIC_VIS_EXPRESSION_NAME,
WAFFLE_VIS_EXPRESSION_NAME,
PARTITION_LABELS_FUNCTION,
} from '../constants';
import {
RenderValue,
@ -91,3 +92,10 @@ export enum ChartTypes {
MOSAIC = 'mosaic',
WAFFLE = 'waffle',
}
export type PartitionLabelsExpressionFunctionDefinition = ExpressionFunctionDefinition<
typeof PARTITION_LABELS_FUNCTION,
Datatable | null,
PartitionLabelsArguments,
ExpressionValuePartitionLabels
>;

View file

@ -32,6 +32,7 @@
],
"optionalPlugins": [
"expressionLegacyMetricVis",
"expressionPartitionVis",
"usageCollection",
"taskManager",
"globalSearch",

View file

@ -5,11 +5,24 @@
* 2.0.
*/
import type { Ast, AstFunction } from '@kbn/interpreter';
import type { Ast } from '@kbn/interpreter';
import { Position } from '@elastic/charts';
import type { PaletteOutput, PaletteRegistry } from '@kbn/coloring';
import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/public';
import type {
LabelPositions,
MosaicVisExpressionFunctionDefinition,
PartitionLabelsExpressionFunctionDefinition,
PieVisExpressionFunctionDefinition,
TreemapVisExpressionFunctionDefinition,
ValueFormats,
LegendDisplay as PartitionVisLegendDisplay,
WaffleVisExpressionFunctionDefinition,
} from '@kbn/expression-partition-vis-plugin/common';
import { ExpressionFunctionTheme } from '@kbn/expressions-plugin/common';
import { ExpressionFunctionVisDimension } from '@kbn/visualizations-plugin/common';
import type { CollapseExpressionFunction } from '../../../common/expressions';
import type { Operation, DatasourcePublicAPI, DatasourceLayers } from '../../types';
import { DEFAULT_PERCENT_DECIMALS } from './constants';
import { shouldShowValuesInLegend } from './render_helpers';
@ -45,15 +58,6 @@ type GenerateExpressionAstFunction = (
paletteService: PaletteRegistry
) => Ast | null;
type GenerateExpressionAstArguments = (
state: PieVisualizationState,
attributes: Attributes,
operations: OperationColumnId[],
layer: PieLayerState,
datasourceLayers: DatasourceLayers,
paletteService: PaletteRegistry
) => Ast['chain'][number]['arguments'];
type GenerateLabelsAstArguments = (
state: PieVisualizationState,
attributes: Attributes,
@ -74,30 +78,25 @@ export const getSortedGroups = (
return Array.from(new Set(originalOrder?.concat(layer[accessor] ?? [])));
};
const prepareDimension = (accessor: string) => {
const visdimension = buildExpressionFunction('visdimension', { accessor });
return buildExpression([visdimension]).toAst();
};
const prepareDimension = (accessor: string) =>
buildExpression([
buildExpressionFunction<ExpressionFunctionVisDimension>('visdimension', { accessor }),
]).toAst();
const generateCommonLabelsAstArgs: GenerateLabelsAstArguments = (state, attributes, layer) => {
const show = [!attributes.isPreview && layer.categoryDisplay !== CategoryDisplay.HIDE];
const position = layer.categoryDisplay !== CategoryDisplay.HIDE ? [layer.categoryDisplay] : [];
const values = [layer.numberDisplay !== NumberDisplay.HIDDEN];
const valuesFormat = layer.numberDisplay !== NumberDisplay.HIDDEN ? [layer.numberDisplay] : [];
const percentDecimals = [layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS];
const show = !attributes.isPreview && layer.categoryDisplay !== CategoryDisplay.HIDE;
const position =
layer.categoryDisplay !== CategoryDisplay.HIDE ? (layer.categoryDisplay as LabelPositions) : [];
const values = layer.numberDisplay !== NumberDisplay.HIDDEN;
const valuesFormat =
layer.numberDisplay !== NumberDisplay.HIDDEN ? (layer.numberDisplay as ValueFormats) : [];
const percentDecimals = layer.percentDecimals ?? DEFAULT_PERCENT_DECIMALS;
const partitionLabelsFn = buildExpressionFunction<PartitionLabelsExpressionFunctionDefinition>(
'partitionLabels',
{ show, position, values, valuesFormat, percentDecimals }
);
return [
{
type: 'expression',
chain: [
{
type: 'function',
function: 'partitionLabels',
arguments: { show, position, values, valuesFormat, percentDecimals },
},
],
},
];
return [buildExpression([partitionLabelsFn]).toAst()];
};
const generateWaffleLabelsAstArguments: GenerateLabelsAstArguments = (...args) => {
@ -117,29 +116,22 @@ const generatePaletteAstArguments = (
): [Ast] =>
palette
? [
{
type: 'expression',
chain: [
{
type: 'function',
function: 'theme',
arguments: {
variable: ['palette'],
default: [paletteService.get(palette.name).toExpression(palette.params)],
},
},
],
},
buildExpression([
buildExpressionFunction<ExpressionFunctionTheme>('theme', {
variable: 'palette',
default: paletteService.get(palette.name).toExpression(palette.params),
}),
]).toAst(),
]
: [paletteService.get('default').toExpression()];
const generateCommonArguments: GenerateExpressionAstArguments = (
state,
attributes,
operations,
layer,
datasourceLayers,
paletteService
const generateCommonArguments = (
state: PieVisualizationState,
attributes: Attributes,
operations: OperationColumnId[],
layer: PieLayerState,
datasourceLayers: DatasourceLayers,
paletteService: PaletteRegistry
) => {
return {
labels: generateCommonLabelsAstArgs(state, attributes, layer),
@ -147,108 +139,81 @@ const generateCommonArguments: GenerateExpressionAstArguments = (
.filter(({ columnId }) => !isCollapsed(columnId, layer))
.map(({ columnId }) => columnId)
.map(prepareDimension),
metric: layer.metric ? [prepareDimension(layer.metric)] : [],
legendDisplay: [attributes.isPreview ? LegendDisplay.HIDE : layer.legendDisplay],
legendPosition: [layer.legendPosition || Position.Right],
maxLegendLines: [layer.legendMaxLines ?? 1],
legendSize: layer.legendSize ? [layer.legendSize] : [],
nestedLegend: [!!layer.nestedLegend],
truncateLegend: [
metric: layer.metric ? prepareDimension(layer.metric) : '',
legendDisplay: (attributes.isPreview
? LegendDisplay.HIDE
: layer.legendDisplay) as PartitionVisLegendDisplay,
legendPosition: layer.legendPosition || Position.Right,
maxLegendLines: layer.legendMaxLines ?? 1,
legendSize: layer.legendSize,
nestedLegend: !!layer.nestedLegend,
truncateLegend:
layer.truncateLegend ?? getDefaultVisualValuesForLayer(state, datasourceLayers).truncateText,
],
palette: generatePaletteAstArguments(paletteService, state.palette),
addTooltip: false,
};
};
const generatePieVisAst: GenerateExpressionAstFunction = (...rest) => ({
type: 'expression',
chain: [
{
type: 'function',
function: 'pieVis',
arguments: {
...generateCommonArguments(...rest),
respectSourceOrder: [false],
startFromSecondLargestSlice: [true],
},
},
],
});
const generatePieVisAst: GenerateExpressionAstFunction = (...rest) =>
buildExpression([
buildExpressionFunction<PieVisExpressionFunctionDefinition>('pieVis', {
...generateCommonArguments(...rest),
respectSourceOrder: false,
startFromSecondLargestSlice: true,
isDonut: false,
}),
]).toAst();
const generateDonutVisAst: GenerateExpressionAstFunction = (...rest) => {
const [, , , layer] = rest;
return {
type: 'expression',
chain: [
{
type: 'function',
function: 'pieVis',
arguments: {
...generateCommonArguments(...rest),
respectSourceOrder: [false],
isDonut: [true],
startFromSecondLargestSlice: [true],
emptySizeRatio: [layer.emptySizeRatio ?? EmptySizeRatios.SMALL],
},
},
],
};
return buildExpression([
buildExpressionFunction<PieVisExpressionFunctionDefinition>('pieVis', {
...generateCommonArguments(...rest),
respectSourceOrder: false,
isDonut: true,
startFromSecondLargestSlice: true,
emptySizeRatio: layer.emptySizeRatio ?? EmptySizeRatios.SMALL,
}),
]).toAst();
};
const generateTreemapVisAst: GenerateExpressionAstFunction = (...rest) => {
const [, , , layer] = rest;
return {
type: 'expression',
chain: [
{
type: 'function',
function: 'treemapVis',
arguments: {
...generateCommonArguments(...rest),
nestedLegend: [!!layer.nestedLegend],
},
},
],
};
return buildExpression([
buildExpressionFunction<TreemapVisExpressionFunctionDefinition>('treemapVis', {
...generateCommonArguments(...rest),
nestedLegend: !!layer.nestedLegend,
}),
]).toAst();
};
const generateMosaicVisAst: GenerateExpressionAstFunction = (...rest) => ({
type: 'expression',
chain: [
{
type: 'function',
function: 'mosaicVis',
arguments: {
...generateCommonArguments(...rest),
// flip order of bucket dimensions so the rows are fetched before the columns to keep them stable
buckets: rest[2]
.filter(({ columnId }) => !isCollapsed(columnId, rest[3]))
.reverse()
.map((o) => o.columnId)
.map(prepareDimension),
},
},
],
});
const generateMosaicVisAst: GenerateExpressionAstFunction = (...rest) =>
buildExpression([
buildExpressionFunction<MosaicVisExpressionFunctionDefinition>('mosaicVis', {
...generateCommonArguments(...rest),
// flip order of bucket dimensions so the rows are fetched before the columns to keep them stable
buckets: rest[2]
.filter(({ columnId }) => !isCollapsed(columnId, rest[3]))
.reverse()
.map((o) => o.columnId)
.map(prepareDimension),
}),
]).toAst();
const generateWaffleVisAst: GenerateExpressionAstFunction = (...rest) => {
const { buckets, nestedLegend, ...args } = generateCommonArguments(...rest);
const [state, attributes, , layer] = rest;
return {
type: 'expression',
chain: [
{
type: 'function',
function: 'waffleVis',
arguments: {
...args,
bucket: buckets,
labels: generateWaffleLabelsAstArguments(state, attributes, layer),
showValuesInLegend: [shouldShowValuesInLegend(layer, state.shape)],
},
},
],
};
return buildExpression([
buildExpressionFunction<WaffleVisExpressionFunctionDefinition>('waffleVis', {
...args,
bucket: buckets,
labels: generateWaffleLabelsAstArguments(state, attributes, layer),
showValuesInLegend: shouldShowValuesInLegend(layer, state.shape),
}),
]).toAst();
};
const generateExprAst: GenerateExpressionAstFunction = (state, ...restArgs) =>
@ -306,15 +271,11 @@ function expressionHelper(
...groups
.filter((columnId) => layer.collapseFns?.[columnId])
.map((columnId) => {
return {
type: 'function',
function: 'lens_collapse',
arguments: {
by: groups.filter((chk) => chk !== columnId),
metric: [layer.metric],
fn: [layer.collapseFns![columnId]!],
},
} as AstFunction;
return buildExpressionFunction<CollapseExpressionFunction>('lens_collapse', {
by: groups.filter((chk) => chk !== columnId),
metric: layer.metric ? [layer.metric] : [],
fn: [layer.collapseFns![columnId]!],
}).toAst();
}),
...(visualizationAst ? visualizationAst.chain : []),
],

View file

@ -31,6 +31,7 @@
{ "path": "../../../src/plugins/embeddable/tsconfig.json"},
{ "path": "../../../src/plugins/presentation_util/tsconfig.json"},
{ "path": "../../../src/plugins/field_formats/tsconfig.json"},
{ "path": "../../../src/plugins/chart_expressions/expression_partition_vis/tsconfig.json"},
{ "path": "../../../src/plugins/chart_expressions/expression_heatmap/tsconfig.json"},
{ "path": "../../../src/plugins/chart_expressions/expression_gauge/tsconfig.json"},
{ "path": "../../../src/plugins/chart_expressions/expression_legacy_metric/tsconfig.json"},