"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildXYExpression = void 0; exports.getScaleType = getScaleType; exports.toExpression = exports.getSortedAccessors = void 0; exports.toPreviewExpression = toPreviewExpression; var _charts = require("@elastic/charts"); var _common = require("@kbn/expressions-plugin/common"); var _eventAnnotationCommon = require("@kbn/event-annotation-common"); var _public = require("@kbn/visualizations-plugin/public"); var _public2 = require("@kbn/expression-xy-plugin/public"); var _state_helpers = require("./state_helpers"); var _color_assignment = require("./color_assignment"); var _datasource_default_values = require("../../shared_components/datasource_default_values"); var _visualization_helpers = require("./visualization_helpers"); var _helpers = require("./annotations/helpers"); var _shared_components = require("../../shared_components"); var _marker_decoration_settings = require("./xy_config_panel/shared/marker_decoration_settings"); /* * 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 getSortedAccessors = (datasource, layer) => { const originalOrder = datasource ? datasource.getTableSpec().map(({ columnId }) => columnId).filter(columnId => layer.accessors.includes(columnId)) : layer.accessors; // When we add a column it could be empty, and therefore have no order return Array.from(new Set(originalOrder.concat(layer.accessors))); }; exports.getSortedAccessors = getSortedAccessors; const toExpression = (state, datasourceLayers, paletteService, datasourceExpressionsByLayers, eventAnnotationService) => { if (!state || !state.layers.length) { return null; } const metadata = {}; state.layers.forEach(layer => { metadata[layer.layerId] = {}; const datasource = datasourceLayers[layer.layerId]; if (datasource) { datasource.getTableSpec().forEach(column => { var _datasourceLayers$lay, _datasourceLayers$lay2; const operation = (_datasourceLayers$lay = (_datasourceLayers$lay2 = datasourceLayers[layer.layerId]) === null || _datasourceLayers$lay2 === void 0 ? void 0 : _datasourceLayers$lay2.getOperationForColumnId(column.columnId)) !== null && _datasourceLayers$lay !== void 0 ? _datasourceLayers$lay : null; metadata[layer.layerId][column.columnId] = operation; }); } }); return buildXYExpression(state, metadata, datasourceLayers, paletteService, datasourceExpressionsByLayers, eventAnnotationService); }; exports.toExpression = toExpression; const simplifiedLayerExpression = { [_public2.LayerTypes.DATA]: layer => ({ ...layer, simpleView: true }), [_public2.LayerTypes.REFERENCELINE]: layer => { var _layer$yConfig; return { ...layer, simpleView: true, yConfig: (_layer$yConfig = layer.yConfig) === null || _layer$yConfig === void 0 ? void 0 : _layer$yConfig.map(({ ...rest }) => ({ ...rest, lineWidth: 1, icon: undefined, textVisibility: false })) }; }, [_public2.LayerTypes.ANNOTATIONS]: layer => ({ ...layer, simpleView: true }) }; function toPreviewExpression(state, datasourceLayers, paletteService, datasourceExpressionsByLayers, eventAnnotationService) { return toExpression({ ...state, layers: state.layers.map(layer => (0, _visualization_helpers.getLayerTypeOptions)(layer, simplifiedLayerExpression)), // hide legend for preview legend: { ...state.legend, isVisible: false }, valueLabels: 'hide' }, datasourceLayers, paletteService, datasourceExpressionsByLayers, eventAnnotationService); } function getScaleType(metadata, defaultScale) { if (!metadata) { return defaultScale; } // use scale information if available if (metadata.scale === 'ordinal') { return _charts.ScaleType.Ordinal; } if (metadata.scale === 'interval' || metadata.scale === 'ratio') { return metadata.dataType === 'date' ? _charts.ScaleType.Time : _charts.ScaleType.Linear; } // fall back to data type if necessary switch (metadata.dataType) { case 'boolean': case 'string': case 'ip': return _charts.ScaleType.Ordinal; case 'date': return _charts.ScaleType.Time; default: return _charts.ScaleType.Linear; } } const buildXYExpression = (state, metadata, datasourceLayers, paletteService, datasourceExpressionsByLayers, eventAnnotationService) => { var _state$axisTitlesVisi, _state$axisTitlesVisi2, _state$tickLabelsVisi, _state$tickLabelsVisi2, _state$gridlinesVisib, _state$gridlinesVisib2, _state$labelsOrientat, _state$labelsOrientat2, _state$axisTitlesVisi3, _state$axisTitlesVisi4, _state$tickLabelsVisi3, _state$tickLabelsVisi4, _state$gridlinesVisib3, _state$gridlinesVisib4, _state$labelsOrientat3, _state$labelsOrientat4, _state$legend$shouldT, _state$axisTitlesVisi5, _state$axisTitlesVisi6, _state$tickLabelsVisi5, _state$tickLabelsVisi6, _state$gridlinesVisib5, _state$gridlinesVisib6, _state$labelsOrientat5, _state$labelsOrientat6, _state$xExtent, _validDataLayers$, _metadata$validDataLa, _metadata$validDataLa2, _validDataLayers$2, _validDataLayers$3; const validDataLayers = (0, _visualization_helpers.getDataLayers)(state.layers).filter(layer => Boolean(layer.accessors.length)).map(layer => ({ ...layer, accessors: getSortedAccessors(datasourceLayers[layer.layerId], layer) })); // sorting doesn't change anything so we don't sort reference layers (TODO: should we make it work?) const validReferenceLayers = (0, _visualization_helpers.getReferenceLayers)(state.layers).filter(layer => Boolean(layer.accessors.length)); const uniqueLabels = (0, _helpers.getUniqueLabels)(state.layers); const validAnnotationsLayers = (0, _visualization_helpers.getAnnotationsLayers)(state.layers).filter(layer => Boolean(layer.annotations.length)).map(layer => { return { ...layer, ignoreGlobalFilters: layer.ignoreGlobalFilters, annotations: layer.annotations.map(c => ({ ...c, label: uniqueLabels[c.id] })) }; }); if (!validDataLayers.length) { return null; } const isLeftAxis = validDataLayers.some(({ yConfig }) => yConfig === null || yConfig === void 0 ? void 0 : yConfig.some(config => config.axisMode === _charts.Position.Left)); const isRightAxis = validDataLayers.some(({ yConfig }) => yConfig === null || yConfig === void 0 ? void 0 : yConfig.some(config => config.axisMode === _charts.Position.Right)); const yAxisConfigs = [{ position: _charts.Position.Left, extent: state === null || state === void 0 ? void 0 : state.yLeftExtent, showTitle: (_state$axisTitlesVisi = state === null || state === void 0 ? void 0 : (_state$axisTitlesVisi2 = state.axisTitlesVisibilitySettings) === null || _state$axisTitlesVisi2 === void 0 ? void 0 : _state$axisTitlesVisi2.yLeft) !== null && _state$axisTitlesVisi !== void 0 ? _state$axisTitlesVisi : true, title: state.yTitle || '', showLabels: (_state$tickLabelsVisi = state === null || state === void 0 ? void 0 : (_state$tickLabelsVisi2 = state.tickLabelsVisibilitySettings) === null || _state$tickLabelsVisi2 === void 0 ? void 0 : _state$tickLabelsVisi2.yLeft) !== null && _state$tickLabelsVisi !== void 0 ? _state$tickLabelsVisi : true, showGridLines: (_state$gridlinesVisib = state === null || state === void 0 ? void 0 : (_state$gridlinesVisib2 = state.gridlinesVisibilitySettings) === null || _state$gridlinesVisib2 === void 0 ? void 0 : _state$gridlinesVisib2.yLeft) !== null && _state$gridlinesVisib !== void 0 ? _state$gridlinesVisib : true, labelsOrientation: (_state$labelsOrientat = state === null || state === void 0 ? void 0 : (_state$labelsOrientat2 = state.labelsOrientation) === null || _state$labelsOrientat2 === void 0 ? void 0 : _state$labelsOrientat2.yLeft) !== null && _state$labelsOrientat !== void 0 ? _state$labelsOrientat : 0, scaleType: state.yLeftScale || 'linear' }, { position: _charts.Position.Right, extent: state === null || state === void 0 ? void 0 : state.yRightExtent, showTitle: (_state$axisTitlesVisi3 = state === null || state === void 0 ? void 0 : (_state$axisTitlesVisi4 = state.axisTitlesVisibilitySettings) === null || _state$axisTitlesVisi4 === void 0 ? void 0 : _state$axisTitlesVisi4.yRight) !== null && _state$axisTitlesVisi3 !== void 0 ? _state$axisTitlesVisi3 : true, title: state.yRightTitle || '', showLabels: (_state$tickLabelsVisi3 = state === null || state === void 0 ? void 0 : (_state$tickLabelsVisi4 = state.tickLabelsVisibilitySettings) === null || _state$tickLabelsVisi4 === void 0 ? void 0 : _state$tickLabelsVisi4.yRight) !== null && _state$tickLabelsVisi3 !== void 0 ? _state$tickLabelsVisi3 : true, showGridLines: (_state$gridlinesVisib3 = state === null || state === void 0 ? void 0 : (_state$gridlinesVisib4 = state.gridlinesVisibilitySettings) === null || _state$gridlinesVisib4 === void 0 ? void 0 : _state$gridlinesVisib4.yRight) !== null && _state$gridlinesVisib3 !== void 0 ? _state$gridlinesVisib3 : true, labelsOrientation: (_state$labelsOrientat3 = state === null || state === void 0 ? void 0 : (_state$labelsOrientat4 = state.labelsOrientation) === null || _state$labelsOrientat4 === void 0 ? void 0 : _state$labelsOrientat4.yRight) !== null && _state$labelsOrientat3 !== void 0 ? _state$labelsOrientat3 : 0, scaleType: state.yRightScale || 'linear' }]; if (isLeftAxis) { yAxisConfigs.push({ id: _charts.Position.Left, position: _charts.Position.Left, // we need also settings from global config here so that default's doesn't override it ...yAxisConfigs[0] }); } if (isRightAxis) { yAxisConfigs.push({ id: _charts.Position.Right, position: _charts.Position.Right, // we need also settings from global config here so that default's doesn't override it ...yAxisConfigs[1] }); } const isValidAnnotation = a => { var _a$filter; return (0, _eventAnnotationCommon.isManualPointAnnotationConfig)(a) || (0, _eventAnnotationCommon.isRangeAnnotationConfig)(a) || a.filter && ((_a$filter = a.filter) === null || _a$filter === void 0 ? void 0 : _a$filter.query) !== ''; }; const legendConfigFn = (0, _common.buildExpressionFunction)('legendConfig', { isVisible: state.legend.isVisible, showSingleSeries: state.legend.showSingleSeries, position: !state.legend.isInside ? state.legend.position : [], isInside: state.legend.isInside ? state.legend.isInside : undefined, legendSize: state.legend.isInside ? undefined : state.legend.position === _charts.Position.Top || state.legend.position === _charts.Position.Bottom ? _public.LegendSize.AUTO : state.legend.legendSize ? state.legend.legendSize : undefined, horizontalAlignment: state.legend.horizontalAlignment && state.legend.isInside ? state.legend.horizontalAlignment : undefined, verticalAlignment: state.legend.verticalAlignment && state.legend.isInside ? state.legend.verticalAlignment : undefined, // ensure that even if the user types more than 5 columns // we will only show 5 floatingColumns: state.legend.floatingColumns && state.legend.isInside ? Math.min(5, state.legend.floatingColumns) : [], maxLines: state.legend.maxLines, shouldTruncate: (_state$legend$shouldT = state.legend.shouldTruncate) !== null && _state$legend$shouldT !== void 0 ? _state$legend$shouldT : (0, _datasource_default_values.getDefaultVisualValuesForLayer)(state, datasourceLayers).truncateText }); const xAxisConfigFn = (0, _common.buildExpressionFunction)('xAxisConfig', { id: 'x', position: 'bottom', title: state.xTitle || '', showTitle: (_state$axisTitlesVisi5 = state === null || state === void 0 ? void 0 : (_state$axisTitlesVisi6 = state.axisTitlesVisibilitySettings) === null || _state$axisTitlesVisi6 === void 0 ? void 0 : _state$axisTitlesVisi6.x) !== null && _state$axisTitlesVisi5 !== void 0 ? _state$axisTitlesVisi5 : true, showLabels: (_state$tickLabelsVisi5 = state === null || state === void 0 ? void 0 : (_state$tickLabelsVisi6 = state.tickLabelsVisibilitySettings) === null || _state$tickLabelsVisi6 === void 0 ? void 0 : _state$tickLabelsVisi6.x) !== null && _state$tickLabelsVisi5 !== void 0 ? _state$tickLabelsVisi5 : true, showGridLines: (_state$gridlinesVisib5 = state === null || state === void 0 ? void 0 : (_state$gridlinesVisib6 = state.gridlinesVisibilitySettings) === null || _state$gridlinesVisib6 === void 0 ? void 0 : _state$gridlinesVisib6.x) !== null && _state$gridlinesVisib5 !== void 0 ? _state$gridlinesVisib5 : true, labelsOrientation: (_state$labelsOrientat5 = state === null || state === void 0 ? void 0 : (_state$labelsOrientat6 = state.labelsOrientation) === null || _state$labelsOrientat6 === void 0 ? void 0 : _state$labelsOrientat6.x) !== null && _state$labelsOrientat5 !== void 0 ? _state$labelsOrientat5 : 0, extent: state.xExtent || validDataLayers.some(layer => (0, _shared_components.hasNumericHistogramDimension)(datasourceLayers[layer.layerId], layer.xAccessor)) ? [(0, _shared_components.axisExtentConfigToExpression)((_state$xExtent = state.xExtent) !== null && _state$xExtent !== void 0 ? _state$xExtent : { mode: 'dataBounds', niceValues: true })] : undefined }); const layeredXyVisFn = (0, _common.buildExpressionFunction)('layeredXyVis', { legend: (0, _common.buildExpression)([legendConfigFn]).toAst(), fittingFunction: state.fittingFunction || 'None', endValue: state.endValue || 'None', emphasizeFitting: state.emphasizeFitting || false, fillOpacity: state.fillOpacity || 0.3, valueLabels: (state === null || state === void 0 ? void 0 : state.valueLabels) || 'hide', hideEndzones: (state === null || state === void 0 ? void 0 : state.hideEndzones) || false, addTimeMarker: (state === null || state === void 0 ? void 0 : state.showCurrentTimeMarker) || false, valuesInLegend: (state === null || state === void 0 ? void 0 : state.valuesInLegend) || false, yAxisConfigs: [...yAxisConfigsToExpression(yAxisConfigs)], xAxisConfig: (0, _common.buildExpression)([xAxisConfigFn]).toAst(), showTooltip: [], layers: [...validDataLayers.map(layer => dataLayerToExpression(layer, yAxisConfigs, datasourceLayers[layer.layerId], metadata, paletteService, datasourceExpressionsByLayers[layer.layerId], state.curveType || 'LINEAR')), ...validReferenceLayers.map(layer => referenceLineLayerToExpression(layer, datasourceLayers[layer.layerId], datasourceExpressionsByLayers[layer.layerId]))], annotations: validAnnotationsLayers.length && validAnnotationsLayers.flatMap(l => l.annotations.filter(isValidAnnotation)).length ? [(0, _common.buildExpression)([(0, _common.buildExpressionFunction)('event_annotations_result', { layers: validAnnotationsLayers.map(layer => annotationLayerToExpression(layer, eventAnnotationService)), datatable: eventAnnotationService.toFetchExpression({ interval: ((_validDataLayers$ = validDataLayers[0]) === null || _validDataLayers$ === void 0 ? void 0 : _validDataLayers$.xAccessor) && ((_metadata$validDataLa = metadata[(_validDataLayers$2 = validDataLayers[0]) === null || _validDataLayers$2 === void 0 ? void 0 : _validDataLayers$2.layerId]) === null || _metadata$validDataLa === void 0 ? void 0 : (_metadata$validDataLa2 = _metadata$validDataLa[(_validDataLayers$3 = validDataLayers[0]) === null || _validDataLayers$3 === void 0 ? void 0 : _validDataLayers$3.xAccessor]) === null || _metadata$validDataLa2 === void 0 ? void 0 : _metadata$validDataLa2.interval) || 'auto', groups: validAnnotationsLayers.map(layer => ({ ignoreGlobalFilters: layer.ignoreGlobalFilters, indexPatternId: layer.indexPatternId, annotations: layer.annotations.filter(isValidAnnotation) })) }) })]).toAst()] : [] }); return (0, _common.buildExpression)([layeredXyVisFn]).toAst(); }; exports.buildXYExpression = buildXYExpression; const yAxisConfigsToExpression = yAxisConfigs => { return yAxisConfigs.map(axis => { var _axis$extent, _axis$showTitle, _axis$showLabels, _axis$showGridLines; return (0, _common.buildExpression)([(0, _common.buildExpressionFunction)('yAxisConfig', { id: axis.id, position: axis.position, extent: (0, _shared_components.axisExtentConfigToExpression)((_axis$extent = axis.extent) !== null && _axis$extent !== void 0 ? _axis$extent : { mode: 'full', niceValues: true }), showTitle: (_axis$showTitle = axis.showTitle) !== null && _axis$showTitle !== void 0 ? _axis$showTitle : true, title: axis.title, showLabels: (_axis$showLabels = axis.showLabels) !== null && _axis$showLabels !== void 0 ? _axis$showLabels : true, showGridLines: (_axis$showGridLines = axis.showGridLines) !== null && _axis$showGridLines !== void 0 ? _axis$showGridLines : true, labelsOrientation: axis.labelsOrientation, scaleType: axis.scaleType })]).toAst(); }); }; const referenceLineLayerToExpression = (layer, datasourceLayer, datasourceExpression) => { const referenceLineLayerFn = (0, _common.buildExpressionFunction)('referenceLineLayer', { layerId: layer.layerId, decorations: layer.yConfig ? layer.yConfig.map(yConfig => extendedYConfigToRLDecorationConfigExpression(yConfig, _color_assignment.defaultReferenceLineColor)) : [], accessors: layer.accessors, columnToLabel: JSON.stringify((0, _state_helpers.getColumnToLabelMap)(layer, datasourceLayer)), ...(datasourceExpression && datasourceExpression.chain.length ? { table: datasourceExpression } : {}) }); return (0, _common.buildExpression)([referenceLineLayerFn]).toAst(); }; const annotationLayerToExpression = (layer, eventAnnotationService) => { const extendedAnnotationLayerFn = (0, _common.buildExpressionFunction)('extendedAnnotationLayer', { simpleView: Boolean(layer.simpleView), layerId: layer.layerId, annotations: eventAnnotationService.toExpression(layer.annotations || []) }); return (0, _common.buildExpression)([extendedAnnotationLayerFn]).toAst(); }; const dataLayerToExpression = (layer, yAxisConfigs, datasourceLayer, metadata, paletteService, datasourceExpression, curveType) => { const columnToLabel = (0, _state_helpers.getColumnToLabelMap)(layer, datasourceLayer); const xAxisOperation = datasourceLayer === null || datasourceLayer === void 0 ? void 0 : datasourceLayer.getOperationForColumnId(layer.xAccessor); const isHistogramDimension = Boolean(xAxisOperation && xAxisOperation.isBucketed && xAxisOperation.scale && xAxisOperation.scale !== 'ordinal'); const dataFromType = layer.seriesType.split('_'); const seriesType = dataFromType[0]; const isPercentage = dataFromType.includes('percentage'); const isStacked = dataFromType.includes('stacked'); const isHorizontal = dataFromType.includes('horizontal'); const collapseFn = (0, _common.buildExpressionFunction)('lens_collapse', { by: layer.xAccessor ? [layer.xAccessor] : [], metric: layer.accessors, fn: [layer.collapseFn] }); const extendedDataLayerFn = (0, _common.buildExpressionFunction)('extendedDataLayer', { layerId: layer.layerId, simpleView: Boolean(layer.simpleView), xAccessor: layer.xAccessor, xScaleType: getScaleType(metadata[layer.layerId][layer.xAccessor], _charts.ScaleType.Linear), isHistogram: isHistogramDimension, isPercentage, isStacked, isHorizontal, splitAccessors: layer.collapseFn || !layer.splitAccessor ? undefined : [layer.splitAccessor], decorations: layer.yConfig ? layer.yConfig.map(yConfig => yConfigToDataDecorationConfigExpression(yConfig, yAxisConfigs)) : undefined, curveType, seriesType: seriesType, showLines: seriesType === 'line' || seriesType === 'area', accessors: layer.accessors, columnToLabel: JSON.stringify(columnToLabel), palette: (0, _common.buildExpression)([layer.palette ? (0, _common.buildExpressionFunction)('theme', { variable: 'palette', default: [paletteService.get(layer.palette.name).toExpression(layer.palette.params)] }) : (0, _common.buildExpressionFunction)('system_palette', { name: 'default' })]).toAst() }); return { type: 'expression', chain: [...(datasourceExpression ? [...datasourceExpression.chain, ...(layer.collapseFn ? [collapseFn.toAst()] : [])] : []), extendedDataLayerFn.toAst()] }; }; const yConfigToDataDecorationConfigExpression = (yConfig, yAxisConfigs, defaultColor) => { var _yAxisConfigs$find, _yConfig$color; const axisId = (_yAxisConfigs$find = yAxisConfigs.find(axis => axis.id && axis.position === yConfig.axisMode)) === null || _yAxisConfigs$find === void 0 ? void 0 : _yAxisConfigs$find.id; const dataDecorationConfigFn = (0, _common.buildExpressionFunction)('dataDecorationConfig', { axisId, forAccessor: yConfig.forAccessor, color: (_yConfig$color = yConfig.color) !== null && _yConfig$color !== void 0 ? _yConfig$color : defaultColor }); return (0, _common.buildExpression)([dataDecorationConfigFn]).toAst(); }; const extendedYConfigToRLDecorationConfigExpression = (yConfig, defaultColor) => { var _yConfig$color2; const referenceLineDecorationConfigFn = (0, _common.buildExpressionFunction)('referenceLineDecorationConfig', { forAccessor: yConfig.forAccessor, position: yConfig.axisMode, color: (_yConfig$color2 = yConfig.color) !== null && _yConfig$color2 !== void 0 ? _yConfig$color2 : defaultColor, lineStyle: yConfig.lineStyle || 'solid', lineWidth: yConfig.lineWidth || 1, fill: yConfig.fill || 'none', icon: (0, _marker_decoration_settings.hasIcon)(yConfig.icon) ? yConfig.icon : undefined, iconPosition: (0, _marker_decoration_settings.hasIcon)(yConfig.icon) || yConfig.textVisibility ? yConfig.iconPosition || 'auto' : 'auto', textVisibility: yConfig.textVisibility || false }); return (0, _common.buildExpression)([referenceLineDecorationConfigFn]).toAst(); };