"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSortedAccessorsForGroup = exports.getColumnToLabelMap = void 0; exports.toExpression = toExpression; exports.toPreviewExpression = toPreviewExpression; var _charts = require("@elastic/charts"); var _public = require("@kbn/expressions-plugin/public"); var _constants = require("./constants"); var _render_helpers = require("./render_helpers"); var _types = require("../../../common/types"); var _constants2 = require("../../../common/constants"); var _datasource_default_values = require("../../shared_components/datasource_default_values"); var _visualization = require("./visualization"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ const getColumnToLabelMap = (columnIds, datasource) => { const columnToLabel = {}; columnIds.forEach(accessor => { const operation = datasource === null || datasource === void 0 ? void 0 : datasource.getOperationForColumnId(accessor); if (operation !== null && operation !== void 0 && operation.label) { columnToLabel[accessor] = operation.label; } }); return columnToLabel; }; exports.getColumnToLabelMap = getColumnToLabelMap; const getSortedAccessorsForGroup = (datasource, layer, accessor) => { var _layer$accessor2; const originalOrder = datasource === null || datasource === void 0 ? void 0 : datasource.getTableSpec().map(({ columnId }) => columnId).filter(columnId => { var _layer$accessor; return (_layer$accessor = layer[accessor]) === null || _layer$accessor === void 0 ? void 0 : _layer$accessor.includes(columnId); }); // When we add a column it could be empty, and therefore have no order return Array.from(new Set(originalOrder === null || originalOrder === void 0 ? void 0 : originalOrder.concat((_layer$accessor2 = layer[accessor]) !== null && _layer$accessor2 !== void 0 ? _layer$accessor2 : []))); }; exports.getSortedAccessorsForGroup = getSortedAccessorsForGroup; const prepareDimension = accessor => (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('visdimension', { accessor })]).toAst(); const generateCommonLabelsAstArgs = (state, attributes, layer, columnToLabelMap) => { var _layer$percentDecimal; const show = !attributes.isPreview && layer.categoryDisplay !== _constants2.CategoryDisplay.HIDE; const position = layer.categoryDisplay !== _constants2.CategoryDisplay.HIDE ? layer.categoryDisplay : []; const values = layer.numberDisplay !== _constants2.NumberDisplay.HIDDEN; const valuesFormat = layer.numberDisplay !== _constants2.NumberDisplay.HIDDEN ? layer.numberDisplay : []; const percentDecimals = (_layer$percentDecimal = layer.percentDecimals) !== null && _layer$percentDecimal !== void 0 ? _layer$percentDecimal : _constants.DEFAULT_PERCENT_DECIMALS; const colorOverrides = layer.allowMultipleMetrics && !(0, _visualization.hasNonCollapsedSliceBy)(layer) ? Object.entries(columnToLabelMap).reduce((acc, [columnId, label]) => { var _layer$colorsByDimens; const color = (_layer$colorsByDimens = layer.colorsByDimension) === null || _layer$colorsByDimens === void 0 ? void 0 : _layer$colorsByDimens[columnId]; if (color) { acc[label] = color; } return acc; }, {}) : {}; const partitionLabelsFn = (0, _public.buildExpressionFunction)('partitionLabels', { show, position, values, valuesFormat, percentDecimals, colorOverrides: JSON.stringify(colorOverrides) }); return [(0, _public.buildExpression)([partitionLabelsFn]).toAst()]; }; const generateWaffleLabelsAstArguments = (...args) => { const [labelsExpr] = generateCommonLabelsAstArgs(...args); const [labels] = labelsExpr.chain; return [{ ...labelsExpr, chain: [{ ...labels, percentDecimals: _constants.DEFAULT_PERCENT_DECIMALS }] }]; }; const generatePaletteAstArguments = (paletteService, palette) => palette ? [(0, _public.buildExpression)([(0, _public.buildExpressionFunction)('theme', { variable: 'palette', default: paletteService.get(palette.name).toExpression(palette.params) })]).toAst()] : [paletteService.get('default').toExpression()]; const generateCommonArguments = (state, attributes, operations, layer, datasourceLayers, paletteService) => { var _layer$legendMaxLines, _layer$secondaryGroup, _layer$secondaryGroup2, _layer$truncateLegend; const datasource = datasourceLayers[layer.layerId]; const columnToLabelMap = getColumnToLabelMap(layer.metrics, datasource); const sortedMetricAccessors = getSortedAccessorsForGroup(datasource, layer, 'metrics'); return { labels: generateCommonLabelsAstArgs(state, attributes, layer, columnToLabelMap), buckets: operations.filter(({ columnId }) => !(0, _visualization.isCollapsed)(columnId, layer)).map(({ columnId }) => columnId).map(prepareDimension), metrics: (layer.allowMultipleMetrics ? sortedMetricAccessors : [sortedMetricAccessors[0]]).map(prepareDimension), metricsToLabels: JSON.stringify(columnToLabelMap), legendDisplay: attributes.isPreview ? _constants2.LegendDisplay.HIDE : layer.legendDisplay, legendPosition: layer.legendPosition || _charts.Position.Right, maxLegendLines: (_layer$legendMaxLines = layer.legendMaxLines) !== null && _layer$legendMaxLines !== void 0 ? _layer$legendMaxLines : 1, legendSize: layer.legendSize, nestedLegend: layer.primaryGroups.length + ((_layer$secondaryGroup = (_layer$secondaryGroup2 = layer.secondaryGroups) === null || _layer$secondaryGroup2 === void 0 ? void 0 : _layer$secondaryGroup2.length) !== null && _layer$secondaryGroup !== void 0 ? _layer$secondaryGroup : 0) > 1 ? Boolean(layer.nestedLegend) : false, truncateLegend: (_layer$truncateLegend = layer.truncateLegend) !== null && _layer$truncateLegend !== void 0 ? _layer$truncateLegend : (0, _datasource_default_values.getDefaultVisualValuesForLayer)(state, datasourceLayers).truncateText, palette: generatePaletteAstArguments(paletteService, state.palette), addTooltip: true }; }; const generatePieVisAst = (...rest) => (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('pieVis', { ...generateCommonArguments(...rest), respectSourceOrder: false, startFromSecondLargestSlice: true, isDonut: false })]).toAst(); const generateDonutVisAst = (...rest) => { var _layer$emptySizeRatio; const [,,, layer] = rest; return (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('pieVis', { ...generateCommonArguments(...rest), respectSourceOrder: false, isDonut: true, startFromSecondLargestSlice: true, emptySizeRatio: (_layer$emptySizeRatio = layer.emptySizeRatio) !== null && _layer$emptySizeRatio !== void 0 ? _layer$emptySizeRatio : _types.EmptySizeRatios.SMALL })]).toAst(); }; const generateTreemapVisAst = (...rest) => { const [,,, layer] = rest; return (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('treemapVis', { ...generateCommonArguments(...rest), nestedLegend: !!layer.nestedLegend })]).toAst(); }; const generateMosaicVisAst = (...rest) => { const { metrics, ...args } = generateCommonArguments(...rest); return (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('mosaicVis', { ...{ ...args, metricsToLabels: undefined }, metric: metrics, // flip order of bucket dimensions so the rows are fetched before the columns to keep them stable buckets: rest[2].filter(({ columnId }) => !(0, _visualization.isCollapsed)(columnId, rest[3])).reverse().map(o => o.columnId).map(prepareDimension) })]).toAst(); }; const generateWaffleVisAst = (...rest) => { const { buckets, nestedLegend, ...args } = generateCommonArguments(...rest); const [state, attributes,, layer, datasourceLayers] = rest; return (0, _public.buildExpression)([(0, _public.buildExpressionFunction)('waffleVis', { ...args, bucket: buckets, labels: generateWaffleLabelsAstArguments(state, attributes, layer, getColumnToLabelMap(layer.metrics, datasourceLayers[layer.layerId])), showValuesInLegend: (0, _render_helpers.shouldShowValuesInLegend)(layer, state.shape) })]).toAst(); }; const generateExprAst = (state, ...restArgs) => ({ [_constants2.PieChartTypes.PIE]: () => generatePieVisAst(state, ...restArgs), [_constants2.PieChartTypes.DONUT]: () => generateDonutVisAst(state, ...restArgs), [_constants2.PieChartTypes.TREEMAP]: () => generateTreemapVisAst(state, ...restArgs), [_constants2.PieChartTypes.MOSAIC]: () => generateMosaicVisAst(state, ...restArgs), [_constants2.PieChartTypes.WAFFLE]: () => generateWaffleVisAst(state, ...restArgs) })[state.shape](); function expressionHelper(state, datasourceLayers, paletteService, attributes = { isPreview: false }, datasourceExpressionsByLayers) { const layer = state.layers[0]; const datasource = datasourceLayers[layer.layerId]; const accessors = Array.from(new Set([getSortedAccessorsForGroup(datasource, layer, 'primaryGroups'), layer.secondaryGroups ? getSortedAccessorsForGroup(datasource, layer, 'secondaryGroups') : []].flat())); const operations = accessors.map(columnId => ({ columnId, operation: datasource === null || datasource === void 0 ? void 0 : datasource.getOperationForColumnId(columnId) })).filter(o => !!o.operation); if (!layer.metrics.length) { return null; } const visualizationAst = generateExprAst(state, attributes, operations, layer, datasourceLayers, paletteService); const datasourceAst = datasourceExpressionsByLayers[layer.layerId]; return { type: 'expression', chain: [...(datasourceAst ? datasourceAst.chain : []), ...accessors.filter(columnId => { var _layer$collapseFns; return (_layer$collapseFns = layer.collapseFns) === null || _layer$collapseFns === void 0 ? void 0 : _layer$collapseFns[columnId]; }).map(columnId => { return (0, _public.buildExpressionFunction)('lens_collapse', { by: accessors.filter(chk => chk !== columnId), metric: layer.metrics, fn: [layer.collapseFns[columnId]] }).toAst(); }), ...(visualizationAst ? visualizationAst.chain : [])] }; } function toExpression(state, datasourceLayers, paletteService, attributes = {}, datasourceExpressionsByLayers = {}) { return expressionHelper(state, datasourceLayers, paletteService, { ...attributes, isPreview: false }, datasourceExpressionsByLayers); } function toPreviewExpression(state, datasourceLayers, paletteService, datasourceExpressionsByLayers = {}) { return expressionHelper(state, datasourceLayers, paletteService, { isPreview: true }, datasourceExpressionsByLayers); }