diff --git a/dev_docs/lens/xy.mdx b/dev_docs/lens/xy.mdx index a53d7ec5a38e1..fc6fb4e6c15bf 100644 --- a/dev_docs/lens/xy.mdx +++ b/dev_docs/lens/xy.mdx @@ -46,7 +46,7 @@ Understanding `LensXYConfig` in detail ### `emphasizeFitting` - **Type:** `boolean` -- **Description:** When set to true, emphasizes the fitting of lines to the data points in line charts, making trends and patterns more apparent. +- **Description:** When set to true a straight line will be used between isolated points in a line chart, a dashed line will be used otherwise. ### `fittingFunction` diff --git a/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.test.ts b/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.test.ts index 0e197b2bfb98b..9b9e9aa96575e 100644 --- a/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.test.ts +++ b/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.test.ts @@ -143,8 +143,8 @@ test('generates xy chart config', async () => { "yLeft": true, "yRight": true, }, - "emphasizeFitting": false, - "fittingFunction": "None", + "emphasizeFitting": true, + "fittingFunction": "Linear", "gridlinesVisibilitySettings": Object { "x": true, "yLeft": true, diff --git a/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.ts b/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.ts index b18a1caec2ffa..ccf68e9905621 100644 --- a/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.ts +++ b/packages/kbn-lens-embeddable-utils/config_builder/charts/xy.ts @@ -51,8 +51,8 @@ function buildVisualizationState(config: LensXYConfig): XYState { hideEndzones: true, preferredSeriesType: 'line', valueLabels: 'hide', - emphasizeFitting: config?.emphasizeFitting ?? false, - fittingFunction: config?.fittingFunction ?? 'None', + emphasizeFitting: config?.emphasizeFitting ?? true, + fittingFunction: config?.fittingFunction ?? 'Linear', yLeftExtent: { mode: config.yBounds?.mode ?? 'full', lowerBound: config.yBounds?.lowerBound, diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_xy_args.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_xy_args.ts index f9f38e19b7396..4be72d333d781 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_xy_args.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_xy_args.ts @@ -40,7 +40,7 @@ export const commonXYArgs: CommonXYFn['args'] = { }, emphasizeFitting: { types: ['boolean'], - default: false, + default: true, help: '', }, valueLabels: { diff --git a/src/plugins/chart_expressions/expression_xy/common/index.ts b/src/plugins/chart_expressions/expression_xy/common/index.ts index dc7c1a7c6334b..6b464a40e87db 100755 --- a/src/plugins/chart_expressions/expression_xy/common/index.ts +++ b/src/plugins/chart_expressions/expression_xy/common/index.ts @@ -10,7 +10,7 @@ export const PLUGIN_ID = 'expressionXy'; export const PLUGIN_NAME = 'expressionXy'; -export { LayerTypes, XYCurveTypes } from './constants'; +export { LayerTypes, XYCurveTypes, FittingFunctions } from './constants'; export type { AllowedXYOverrides, diff --git a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx index e45edccba2779..473562b63ad5e 100644 --- a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx @@ -100,7 +100,6 @@ type GetColorFn = ( type GetPointConfigFn = (config: { xAccessor: string | undefined; markSizeAccessor: string | undefined; - emphasizeFitting?: boolean; showPoints?: boolean; pointsRadius?: number; }) => Partial; @@ -297,18 +296,10 @@ export const getSeriesName: GetSeriesNameFn = ( return splitValues.length > 0 ? splitValues.join(' - ') : yAccessorTitle; }; -const getPointConfig: GetPointConfigFn = ({ - xAccessor, - markSizeAccessor, - emphasizeFitting, - showPoints, - pointsRadius, -}) => { +const getPointConfig: GetPointConfigFn = ({ markSizeAccessor, showPoints, pointsRadius }) => { return { - visible: (showPoints !== undefined ? showPoints : !xAccessor || markSizeAccessor !== undefined) - ? 'always' - : 'never', - radius: pointsRadius !== undefined ? pointsRadius : xAccessor && !emphasizeFitting ? 5 : 0, + visible: showPoints || markSizeAccessor ? 'always' : 'never', + radius: pointsRadius, fill: markSizeAccessor ? ColorVariant.Series : undefined, }; }; @@ -550,7 +541,6 @@ export const getSeriesProps: GetSeriesPropsFn = ({ point: getPointConfig({ xAccessor: xColumnId, markSizeAccessor: markSizeColumnId, - emphasizeFitting, showPoints: layer.showPoints, pointsRadius: layer.pointsRadius, }), @@ -567,7 +557,6 @@ export const getSeriesProps: GetSeriesPropsFn = ({ point: getPointConfig({ xAccessor: xColumnId, markSizeAccessor: markSizeColumnId, - emphasizeFitting, showPoints: layer.showPoints, pointsRadius: layer.pointsRadius, }), diff --git a/src/plugins/chart_expressions/expression_xy/public/index.ts b/src/plugins/chart_expressions/expression_xy/public/index.ts index a6e001d5eb5b1..d63ac6c2a5930 100755 --- a/src/plugins/chart_expressions/expression_xy/public/index.ts +++ b/src/plugins/chart_expressions/expression_xy/public/index.ts @@ -15,6 +15,6 @@ export function plugin() { return new ExpressionXyPlugin(); } -export { LayerTypes, XYCurveTypes } from '../common'; +export { LayerTypes, XYCurveTypes, FittingFunctions } from '../common'; export type { ExpressionXyPluginSetup, ExpressionXyPluginStart } from './types'; diff --git a/x-pack/plugins/lens/public/visualizations/xy/to_expression.test.ts b/x-pack/plugins/lens/public/visualizations/xy/to_expression.test.ts index 08a013d036d5e..0571ca43f0bc7 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/to_expression.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/to_expression.test.ts @@ -121,31 +121,30 @@ describe('#toExpression', () => { ).toMatchSnapshot(); }); - it('should default the fitting function to None', () => { - expect( - ( - xyVisualization.toExpression( + it('should default the fitting function to Linear', () => { + const ast = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + valueLabels: 'hide', + preferredSeriesType: 'bar', + layers: [ { - legend: { position: Position.Bottom, isVisible: true }, - valueLabels: 'hide', - preferredSeriesType: 'bar', - layers: [ - { - layerId: 'first', - layerType: LayerTypes.DATA, - seriesType: 'area', - splitAccessor: 'd', - xAccessor: 'a', - accessors: ['b', 'c'], - }, - ], + layerId: 'first', + layerType: LayerTypes.DATA, + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], }, - frame.datasourceLayers, - undefined, - datasourceExpressionsByLayers - ) as Ast - ).chain[0].arguments.fittingFunction[0] - ).toEqual('None'); + ], + }, + frame.datasourceLayers, + undefined, + datasourceExpressionsByLayers + ) as Ast; + + expect(ast.chain[0].arguments.fittingFunction[0]).toEqual('Linear'); + expect(ast.chain[0].arguments.emphasizeFitting[0]).toEqual(true); }); it('should default the axisTitles visibility settings to true', () => { diff --git a/x-pack/plugins/lens/public/visualizations/xy/to_expression.ts b/x-pack/plugins/lens/public/visualizations/xy/to_expression.ts index c756c4eb137a9..b249624605791 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/to_expression.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/to_expression.ts @@ -35,6 +35,8 @@ import { XYCurveType, YAxisConfigFn, } from '@kbn/expression-xy-plugin/common'; + +import { FittingFunctions } from '@kbn/expression-xy-plugin/public'; import type { EventAnnotationConfig } from '@kbn/event-annotation-common'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; import { SystemPaletteExpressionFunctionDefinition } from '@kbn/charts-plugin/common'; @@ -336,9 +338,9 @@ export const buildXYExpression = ( const layeredXyVisFn = buildExpressionFunction('layeredXyVis', { legend: buildExpression([legendConfigFn]).toAst(), - fittingFunction: state.fittingFunction ?? 'None', + fittingFunction: state.fittingFunction ?? FittingFunctions.LINEAR, endValue: state.endValue ?? 'None', - emphasizeFitting: state.emphasizeFitting ?? false, + emphasizeFitting: state.emphasizeFitting ?? true, minBarHeight: state.minBarHeight ?? 1, fillOpacity: state.fillOpacity ?? 0.3, valueLabels: state.valueLabels ?? 'hide', diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/fitting_function_definitions.ts b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/fitting_function_definitions.ts index c2286a942baca..2ce2cd5f3cd68 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/fitting_function_definitions.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/fitting_function_definitions.ts @@ -7,10 +7,11 @@ import { i18n } from '@kbn/i18n'; import type { FittingFunction } from '@kbn/expression-xy-plugin/common'; +import { FittingFunctions } from '@kbn/expression-xy-plugin/public'; export const fittingFunctionDefinitions: Array<{ id: FittingFunction } & Record> = [ { - id: 'None', + id: FittingFunctions.NONE, title: i18n.translate('xpack.lens.fittingFunctionsTitle.none', { defaultMessage: 'Hide', }), @@ -19,7 +20,7 @@ export const fittingFunctionDefinitions: Array<{ id: FittingFunction } & Record< }), }, { - id: 'Zero', + id: FittingFunctions.ZERO, title: i18n.translate('xpack.lens.fittingFunctionsTitle.zero', { defaultMessage: 'Zero', }), @@ -28,7 +29,7 @@ export const fittingFunctionDefinitions: Array<{ id: FittingFunction } & Record< }), }, { - id: 'Linear', + id: FittingFunctions.LINEAR, title: i18n.translate('xpack.lens.fittingFunctionsTitle.linear', { defaultMessage: 'Linear', }), @@ -37,7 +38,7 @@ export const fittingFunctionDefinitions: Array<{ id: FittingFunction } & Record< }), }, { - id: 'Carry', + id: FittingFunctions.CARRY, title: i18n.translate('xpack.lens.fittingFunctionsTitle.carry', { defaultMessage: 'Last', }), @@ -46,7 +47,7 @@ export const fittingFunctionDefinitions: Array<{ id: FittingFunction } & Record< }), }, { - id: 'Lookahead', + id: FittingFunctions.LOOKAHEAD, title: i18n.translate('xpack.lens.fittingFunctionsTitle.lookahead', { defaultMessage: 'Next', }), diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/missing_values_option.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/missing_values_option.tsx index feda75599e4cc..c600f4fa4bae4 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/missing_values_option.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/missing_values_option.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiIconTip, EuiSuperSelect, EuiSwitch, EuiText } from '@elastic/eui'; import type { FittingFunction, EndValue } from '@kbn/expression-xy-plugin/common'; +import { FittingFunctions } from '@kbn/expression-xy-plugin/public'; import { fittingFunctionDefinitions } from './fitting_function_definitions'; import { endValueDefinitions } from './end_value_definitions'; @@ -25,7 +26,7 @@ export interface MissingValuesOptionProps { export const MissingValuesOptions: React.FC = ({ onFittingFnChange, fittingFunction, - emphasizeFitting, + emphasizeFitting = true, onEmphasizeFittingChange, onEndValueChange, endValue, @@ -78,13 +79,13 @@ export const MissingValuesOptions: React.FC = ({ inputDisplay: title, }; })} - valueOfSelected={fittingFunction || 'None'} + valueOfSelected={fittingFunction || FittingFunctions.LINEAR} onChange={(value) => onFittingFnChange(value)} itemLayoutAlign="top" hasDividers /> - {fittingFunction && fittingFunction !== 'None' && ( + {fittingFunction && fittingFunction !== FittingFunctions.NONE && ( <> = ({ inputDisplay: title, }; })} - valueOfSelected={endValue || 'None'} + valueOfSelected={endValue || FittingFunctions.NONE} onChange={(value) => onEndValueChange(value)} itemLayoutAlign="top" hasDividers diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.test.ts b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.test.ts index 77f79b5db6b1a..c81dea60da719 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.test.ts @@ -633,7 +633,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', layers: [ { accessors: ['price'], @@ -691,7 +691,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', layers: [ { layerId: 'first', @@ -823,7 +823,7 @@ describe('xy_suggestions', () => { const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', - fittingFunction: 'None', + fittingFunction: 'Linear', preferredSeriesType: 'line', layers: [ { @@ -858,7 +858,7 @@ describe('xy_suggestions', () => { const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', - fittingFunction: 'None', + fittingFunction: 'Linear', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, @@ -908,7 +908,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, @@ -967,7 +967,7 @@ describe('xy_suggestions', () => { const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', - fittingFunction: 'None', + fittingFunction: 'Linear', preferredSeriesType: 'bar', layers: [ { @@ -1006,7 +1006,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', layers: [ { accessors: ['price'], @@ -1043,7 +1043,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, @@ -1089,7 +1089,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, @@ -1136,7 +1136,7 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', preferredSeriesType: 'bar', - fittingFunction: 'None', + fittingFunction: 'Linear', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts index 0974e50ef36fe..49531c6b563be 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts @@ -8,7 +8,8 @@ import { i18n } from '@kbn/i18n'; import { partition } from 'lodash'; import { Position } from '@elastic/charts'; -import { LayerTypes } from '@kbn/expression-xy-plugin/public'; +import { FittingFunctions, LayerTypes } from '@kbn/expression-xy-plugin/public'; + import type { SuggestionRequest, VisualizationSuggestion, @@ -573,7 +574,7 @@ function buildSuggestion({ const state: State = { legend: currentState ? currentState.legend : { isVisible: true, position: Position.Right }, valueLabels: currentState?.valueLabels || 'hide', - fittingFunction: currentState?.fittingFunction || 'None', + fittingFunction: currentState?.fittingFunction ?? FittingFunctions.LINEAR, curveType: currentState?.curveType, fillOpacity: currentState?.fillOpacity, xTitle: currentState?.xTitle,