Skip to content

Commit

Permalink
[Lens] PartitionVis expression types improvement. (#144248)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

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

Co-authored-by: Andrew Tate <[email protected]>

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

* Fixed types.

Co-authored-by: Andrew Tate <[email protected]>
Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
3 people authored Nov 3, 2022
1 parent 1855f22 commit f065d66
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type {
TreemapVisExpressionFunctionDefinition,
MosaicVisExpressionFunctionDefinition,
WaffleVisExpressionFunctionDefinition,
PartitionLabelsExpressionFunctionDefinition,
} from './types/expression_functions';

export type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
TREEMAP_VIS_EXPRESSION_NAME,
MOSAIC_VIS_EXPRESSION_NAME,
WAFFLE_VIS_EXPRESSION_NAME,
PARTITION_LABELS_FUNCTION,
} from '../constants';
import {
RenderValue,
Expand Down Expand Up @@ -91,3 +92,10 @@ export enum ChartTypes {
MOSAIC = 'mosaic',
WAFFLE = 'waffle',
}

export type PartitionLabelsExpressionFunctionDefinition = ExpressionFunctionDefinition<
typeof PARTITION_LABELS_FUNCTION,
Datatable | null,
PartitionLabelsArguments,
ExpressionValuePartitionLabels
>;
1 change: 1 addition & 0 deletions x-pack/plugins/lens/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
],
"optionalPlugins": [
"expressionLegacyMetricVis",
"expressionPartitionVis",
"usageCollection",
"taskManager",
"globalSearch",
Expand Down
249 changes: 105 additions & 144 deletions x-pack/plugins/lens/public/visualizations/partition/to_expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -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) => {
Expand All @@ -117,138 +116,104 @@ 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),
buckets: operations
.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) =>
Expand Down Expand Up @@ -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 : []),
],
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/lens/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down

0 comments on commit f065d66

Please sign in to comment.