diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts index 0b9667353706..d784b914763e 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts @@ -16,6 +16,12 @@ export interface AxesSettingsConfig { yRight: boolean; } +export interface AxesSettingsStringConfig { + x?: string; + yLeft?: string; + yRight?: string; +} + export interface AxisExtentConfig { mode: 'full' | 'dataBounds' | 'custom'; lowerBound?: number; @@ -44,6 +50,49 @@ export interface YConfig { textVisibility?: boolean; } +export type AxisColorsConfigResult = AxesSettingsStringConfig & { + type: 'lens_xy_axisColorsConfig'; +}; + +export const axisColorsConfig: ExpressionFunctionDefinition< + 'lens_xy_axisColorsConfig', + null, + AxesSettingsStringConfig, + AxisColorsConfigResult +> = { + name: 'lens_xy_axisColorsConfig', + aliases: [], + type: 'lens_xy_axisColorsConfig', + help: `Configure the xy chart's axis titles appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.xAxisColor.help', { + defaultMessage: 'The color of the x-axis.', + }), + }, + yLeft: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.yLeftAxisColor.help', { + defaultMessage: 'The color of the left y-axis.', + }), + }, + yRight: { + types: ['string'], + help: i18n.translate('xpack.lens.xyChart.yRightAxisColor.help', { + defaultMessage: 'The color of the right y-axis.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsStringConfig) { + return { + type: 'lens_xy_axisColorsConfig', + ...args, + }; + }, +}; + export type AxisTitlesVisibilityConfigResult = AxesSettingsConfig & { type: 'lens_xy_axisTitlesVisibilityConfig'; }; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts index f00608135820..9e894ae231f7 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { AxisExtentConfigResult, AxisTitlesVisibilityConfigResult } from './axis_config'; +import type { + AxisColorsConfigResult, + AxisExtentConfigResult, + AxisTitlesVisibilityConfigResult, +} from './axis_config'; import type { FittingFunction } from './fitting_function'; import type { GridlinesConfigResult } from './grid_lines_config'; import type { LayerArgs } from './layer_config'; @@ -30,6 +34,7 @@ export interface XYArgs { layers: LayerArgs[]; fittingFunction?: FittingFunction; axisTitlesVisibilitySettings?: AxisTitlesVisibilityConfigResult; + axisColorSettings?: AxisColorsConfigResult; tickLabelsVisibilitySettings?: TickLabelsConfigResult; gridlinesVisibilitySettings?: GridlinesConfigResult; labelsOrientation?: LabelsOrientationConfigResult; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts index 0e5810544768..a595c352825e 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts @@ -115,6 +115,12 @@ export const xyChart: ExpressionFunctionDefinition< defaultMessage: 'Show x and y axes titles', }), }, + axisColorSettings: { + types: ['lens_xy_axisColorsConfig'], + help: i18n.translate('xpack.lens.xyChart.axisColorSettings.help', { + defaultMessage: 'Defines axis colors', + }), + }, layers: { // eslint-disable-next-line @typescript-eslint/no-explicit-any types: ['lens_xy_layer'] as any, diff --git a/x-pack/plugins/lens/public/expressions.ts b/x-pack/plugins/lens/public/expressions.ts index 22e43addefcd..1dbbbce7e57c 100644 --- a/x-pack/plugins/lens/public/expressions.ts +++ b/x-pack/plugins/lens/public/expressions.ts @@ -11,6 +11,7 @@ import { axisExtentConfig, yAxisConfig, axisTitlesVisibilityConfig, + axisColorsConfig, } from '../common/expressions/xy_chart/axis_config'; import { gridlinesConfig } from '../common/expressions/xy_chart/grid_lines_config'; import { labelsOrientationConfig } from '../common/expressions/xy_chart/labels_orientation_config'; @@ -53,6 +54,7 @@ export const setupExpressions = ( datatableColumn, tickLabelsConfig, axisTitlesVisibilityConfig, + axisColorsConfig, axisExtentConfig, labelsOrientationConfig, getDatatable(formatFactory), diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap index e2566aa22ce9..f4a0da1c42cb 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap @@ -55,7 +55,11 @@ exports[`xy_expression XYChart component it renders area 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -89,7 +93,11 @@ exports[`xy_expression XYChart component it renders area 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -286,7 +294,11 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -320,7 +332,11 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -531,7 +547,11 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -565,7 +585,11 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -776,7 +800,11 @@ exports[`xy_expression XYChart component it renders line 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -810,7 +838,11 @@ exports[`xy_expression XYChart component it renders line 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1007,7 +1039,11 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1041,7 +1077,11 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1246,7 +1286,11 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1280,7 +1324,11 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1499,7 +1547,11 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = position="left" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, @@ -1533,7 +1585,11 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = position="bottom" style={ Object { + "axisLine": Object { + "stroke": undefined, + }, "axisTitle": Object { + "fill": undefined, "padding": undefined, "visible": true, }, diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap index 2af871d58103..479c89270af2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap @@ -5,13 +5,35 @@ Object { "chain": Array [ Object { "arguments": Object { + "axisColorSettings": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "x": Array [ + "#123456", + ], + "yLeft": Array [ + "#654321", + ], + "yRight": Array [ + "#123456", + ], + }, + "function": "lens_xy_axisColorsConfig", + "type": "function", + }, + ], + "type": "expression", + }, + ], "axisTitlesVisibilitySettings": Array [ Object { "chain": Array [ Object { "arguments": Object { "x": Array [ - true, + false, ], "yLeft": Array [ true, diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx index bb3b5bfcbfec..9826f62a6ad7 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -25,11 +25,12 @@ import { PaletteOutput } from 'src/plugins/charts/public'; import { calculateMinInterval, XYChart, XYChartRenderProps } from './expression'; import type { LensMultiTable } from '../../common'; import { layerTypes } from '../../common'; -import { xyChart } from '../../common/expressions'; +import { AxesSettingsStringConfig, xyChart } from '../../common/expressions'; import { layerConfig, legendConfig, tickLabelsConfig, + axisColorsConfig, gridlinesConfig, XYArgs, LegendConfig, @@ -426,6 +427,21 @@ describe('xy_expression', () => { }); }); + test('axisColorsConfig produces the correct arguments', () => { + const args: AxesSettingsStringConfig = { + x: '#x-color', + yLeft: '#yleft-color', + yRight: '#yright-color', + }; + + const result = axisColorsConfig.fn(null, args, createMockExecutionContext()); + + expect(result).toEqual({ + type: 'lens_xy_axisColorsConfig', + ...args, + }); + }); + test('gridlinesConfig produces the correct arguments', () => { const args: AxesSettingsConfig = { x: true, @@ -2695,6 +2711,47 @@ describe('xy_expression', () => { }); }); + describe('axis colors', () => { + test('it should default axis colors to undefined', () => { + const { data, args } = sampleArgs(); + + args.axisColorSettings = undefined; + + const component = shallow( + + ); + + const axes = component.find(Axis); + const [xAxisStyle, yLeftAxisStyle] = [axes.at(0).prop('style'), axes.at(1).prop('style')]; + expect(xAxisStyle?.axisLine?.stroke).toBeUndefined(); + expect(xAxisStyle?.axisTitle?.fill).toBeUndefined(); + expect(yLeftAxisStyle?.axisLine?.stroke).toBeUndefined(); + expect(yLeftAxisStyle?.axisTitle?.fill).toBeUndefined(); + }); + + test('it should apply custom axis colors', () => { + const { data, args } = sampleArgs(); + + args.axisColorSettings = { + x: '#x-axis', + yLeft: '#yleft-axis', + yRight: '#yright-axis', + type: 'lens_xy_axisColorsConfig', + }; + + const component = shallow( + + ); + + const axes = component.find(Axis); + const [xAxisStyle, yLeftAxisStyle] = [axes.at(0).prop('style'), axes.at(1).prop('style')]; + expect(xAxisStyle?.axisLine?.stroke).toBe(args.axisColorSettings.x); + expect(xAxisStyle?.axisTitle?.fill).toBe(args.axisColorSettings.x); + expect(yLeftAxisStyle?.axisLine?.stroke).toBe(args.axisColorSettings.yLeft); + expect(yLeftAxisStyle?.axisTitle?.fill).toBe(args.axisColorSettings.yLeft); + }); + }); + test('it should format the boolean values correctly', () => { const data: LensMultiTable = { type: 'lens_multitable', diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index d22a8034cdf2..9c4bc74d5cc7 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -239,6 +239,7 @@ export function XYChart({ layers, fittingFunction, gridlinesVisibilitySettings, + axisColorSettings, valueLabels, hideEndzones, yLeftExtent, @@ -352,18 +353,14 @@ export function XYChart({ }; const getYAxesStyle = (groupId: 'left' | 'right') => { - const tickVisible = - groupId === 'right' - ? tickLabelsVisibilitySettings?.yRight - : tickLabelsVisibilitySettings?.yLeft; + const whichAxis = groupId === 'right' ? 'yRight' : 'yLeft'; + + const tickVisible = tickLabelsVisibilitySettings[whichAxis]; const style = { tickLabel: { visible: tickVisible, - rotation: - groupId === 'right' - ? args.labelsOrientation?.yRight || 0 - : args.labelsOrientation?.yLeft || 0, + rotation: args.labelsOrientation?.[whichAxis] || 0, padding: referenceLinePaddings[groupId] != null ? { @@ -372,10 +369,7 @@ export function XYChart({ : undefined, }, axisTitle: { - visible: - groupId === 'right' - ? axisTitlesVisibilitySettings?.yRight - : axisTitlesVisibilitySettings?.yLeft, + visible: axisTitlesVisibilitySettings[whichAxis], // if labels are not visible add the padding to the title padding: !tickVisible && referenceLinePaddings[groupId] != null @@ -383,6 +377,10 @@ export function XYChart({ inner: referenceLinePaddings[groupId], } : undefined, + fill: axisColorSettings?.[whichAxis], + }, + axisLine: { + stroke: axisColorSettings?.[whichAxis], }, }; return style; @@ -582,6 +580,10 @@ export function XYChart({ }, axisTitle: { visible: axisTitlesVisibilitySettings.x, + fill: axisColorSettings?.x, + }, + axisLine: { + stroke: axisColorSettings?.x, }, } : { @@ -599,8 +601,13 @@ export function XYChart({ !tickLabelsVisibilitySettings?.x && referenceLinePaddings.bottom != null ? { inner: referenceLinePaddings.bottom } : undefined, + fill: axisColorSettings?.x, + }, + axisLine: { + stroke: axisColorSettings?.x, }, }; + return ( { preferredSeriesType: 'bar', fittingFunction: 'Carry', tickLabelsVisibilitySettings: { x: false, yLeft: true, yRight: true }, + axisTitlesVisibilitySettings: { x: false, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#654321', yRight: '#123456' }, labelsOrientation: { x: 0, yLeft: -90, @@ -136,6 +138,60 @@ describe('#toExpression', () => { }); }); + it('should populate axis colors with empty defaults', () => { + const expression = xyVisualization.toExpression( + { + 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'], + }, + ], + }, + frame.datasourceLayers + ) as Ast; + expect((expression.chain[0].arguments.axisColorSettings[0] as Ast).chain[0].arguments).toEqual({ + x: [], + yLeft: [], + yRight: [], + }); + }); + + it('should respect axis color customizations', () => { + const customColor = '#custom-color'; + const expression = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + valueLabels: 'hide', + preferredSeriesType: 'bar', + axisColors: { x: customColor, yLeft: customColor, yRight: customColor }, + layers: [ + { + layerId: 'first', + layerType: layerTypes.DATA, + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], + }, + ], + }, + frame.datasourceLayers + ) as Ast; + expect((expression.chain[0].arguments.axisColorSettings[0] as Ast).chain[0].arguments).toEqual({ + x: [customColor], + yLeft: [customColor], + yRight: [customColor], + }); + }); + it('should generate an expression without x accessor', () => { const expression = xyVisualization.toExpression( { diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 1cd0bab48cd6..0580e21fde16 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -242,6 +242,22 @@ export const buildExpression = ( ], }, ], + axisColorSettings: [ + { + type: 'expression', + chain: [ + { + type: 'function', + function: 'lens_xy_axisColorsConfig', + arguments: { + x: state?.axisColors?.x ? [state?.axisColors?.x] : [], + yLeft: state?.axisColors?.yLeft ? [state?.axisColors?.yLeft] : [], + yRight: state?.axisColors?.yRight ? [state?.axisColors?.yRight] : [], + }, + }, + ], + }, + ], tickLabelsVisibilitySettings: [ { type: 'expression', diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index 75e80782c5d3..4ccca0bdabf4 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -25,6 +25,7 @@ import type { XYLayerConfig, XYCurveType, AxesSettingsConfig, + AxesSettingsStringConfig, FittingFunction, LabelsOrientationConfig, } from '../../common/expressions'; @@ -43,6 +44,7 @@ export interface XYState { yTitle?: string; yRightTitle?: string; axisTitlesVisibilitySettings?: AxesSettingsConfig; + axisColors?: AxesSettingsStringConfig; tickLabelsVisibilitySettings?: AxesSettingsConfig; gridlinesVisibilitySettings?: AxesSettingsConfig; labelsOrientation?: LabelsOrientationConfig; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.test.tsx index ebe0e536a4d7..cd517e17eea3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.test.tsx @@ -10,6 +10,8 @@ import { shallowWithIntl as shallow } from '@kbn/test/jest'; import { AxisSettingsPopover, AxisSettingsPopoverProps } from './axis_settings_popover'; import { ToolbarPopover } from '../../shared_components'; import { layerTypes } from '../../../common'; +import { EuiColorPicker } from '@elastic/eui'; +import { EuiColorPickerOutput } from '@elastic/eui/src/components/color_picker/color_picker'; describe('Axes Settings', () => { let props: AxisSettingsPopoverProps; @@ -31,6 +33,7 @@ describe('Axes Settings', () => { areTickLabelsVisible: true, areGridlinesVisible: true, isAxisTitleVisible: true, + updateColor: jest.fn(), toggleAxisTitleVisibility: jest.fn(), toggleTickLabelsVisibility: jest.fn(), toggleGridlinesVisibility: jest.fn(), @@ -120,6 +123,24 @@ describe('Axes Settings', () => { expect(component.find('[data-test-subj="lnsshowEndzones"]').prop('checked')).toBe(true); }); + describe('manipulating axis color', () => { + it('starts on default axis color', () => { + const component = shallow(); + expect(component.find(EuiColorPicker).prop('color')).toBeUndefined(); + }); + + it('reports a new color choice', () => { + const component = shallow(); + + const newColor = 'new-color'; + + component.find(EuiColorPicker).prop('onChange')(newColor, {} as EuiColorPickerOutput); + + expect(props.updateColor).toHaveBeenCalledTimes(1); + expect(props.updateColor).toHaveBeenCalledWith(props.axis, newColor); + }); + }); + describe('axis extent', () => { it('hides the extent section if no extent is passed in', () => { const component = shallow(); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.tsx index 4ce1667ee100..143894361a5f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/axis_settings_popover.tsx @@ -18,6 +18,7 @@ import { EuiButtonGroup, htmlIdGenerator, EuiFieldNumber, + EuiColorPicker, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { XYLayerConfig, AxesSettingsConfig, AxisExtentConfig } from '../../../common/expressions'; @@ -49,6 +50,14 @@ export interface AxisSettingsPopoverProps { * Callback to axis title change */ updateTitleState: (value: string) => void; + /** + * Callback to axis color change + */ + updateColor: (axis: AxesSettingsConfigKeys, value: string) => void; + /** + * Determines axis color + */ + color?: string; /** * Determines if the popover is Disabled */ @@ -199,9 +208,11 @@ export const AxisSettingsPopover: React.FunctionComponent + + + updateColor(axis, newColor)} + placeholder={i18n.translate('xpack.lens.xyChart.axisColor.auto', { + defaultMessage: 'Auto', + })} + color={color} + aria-label={axisColorLabel} + /> + { + let newAxisColors: AxesSettingsStringConfig | undefined = { + ...state.axisColors, + ...{ + [axis]: color, + }, + }; + + if (!Object.values(newAxisColors).some(Boolean)) { + newAxisColors = undefined; // clean up + } + + setState({ + ...state, + axisColors: newAxisColors, + }); + }; + const nonOrdinalXAxis = state?.layers.every( (layer) => !layer.xAccessor || @@ -476,6 +496,8 @@ export const XyToolbar = memo(function XyToolbar( layers={state?.layers} axisTitle={state?.yTitle} updateTitleState={(value) => setState({ ...state, yTitle: value })} + color={state?.axisColors?.yLeft} + updateColor={onAxisColorChanged} areTickLabelsVisible={tickLabelsVisibilitySettings.yLeft} toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange} areGridlinesVisible={gridlinesVisibilitySettings.yLeft} @@ -499,6 +521,8 @@ export const XyToolbar = memo(function XyToolbar( layers={state?.layers} axisTitle={state?.xTitle} updateTitleState={(value) => setState({ ...state, xTitle: value })} + color={state?.axisColors?.x} + updateColor={onAxisColorChanged} areTickLabelsVisible={tickLabelsVisibilitySettings.x} toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange} areGridlinesVisible={gridlinesVisibilitySettings.x} @@ -534,6 +558,8 @@ export const XyToolbar = memo(function XyToolbar( layers={state?.layers} axisTitle={state?.yRightTitle} updateTitleState={(value) => setState({ ...state, yRightTitle: value })} + color={state?.axisColors?.yRight} + updateColor={onAxisColorChanged} areTickLabelsVisible={tickLabelsVisibilitySettings.yRight} toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange} areGridlinesVisible={gridlinesVisibilitySettings.yRight} diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index d7b48553ce73..d16227d0b23d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -637,6 +637,7 @@ describe('xy_suggestions', () => { valueLabels: 'hide', fittingFunction: 'None', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#123456', yRight: '#123456' }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, @@ -681,6 +682,7 @@ describe('xy_suggestions', () => { preferredSeriesType: 'bar', fittingFunction: 'None', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#123456', yRight: '#123456' }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, @@ -800,6 +802,7 @@ describe('xy_suggestions', () => { preferredSeriesType: 'bar', fittingFunction: 'None', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#123456', yRight: '#123456' }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, @@ -845,6 +848,7 @@ describe('xy_suggestions', () => { preferredSeriesType: 'bar', fittingFunction: 'None', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#123456', yRight: '#123456' }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, @@ -891,6 +895,7 @@ describe('xy_suggestions', () => { preferredSeriesType: 'bar', fittingFunction: 'None', axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + axisColors: { x: '#123456', yLeft: '#123456', yRight: '#123456' }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts index 2e275c455a4d..f4556f2c91b1 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -540,6 +540,7 @@ function buildSuggestion({ yLeft: true, yRight: true, }, + axisColors: currentState?.axisColors, tickLabelsVisibilitySettings: currentState?.tickLabelsVisibilitySettings || { x: true, yLeft: true, diff --git a/x-pack/plugins/lens/server/expressions/expressions.ts b/x-pack/plugins/lens/server/expressions/expressions.ts index a04ad27d1a27..e60bdf2b81e7 100644 --- a/x-pack/plugins/lens/server/expressions/expressions.ts +++ b/x-pack/plugins/lens/server/expressions/expressions.ts @@ -20,6 +20,7 @@ import { datatableColumn, tickLabelsConfig, axisTitlesVisibilityConfig, + axisColorsConfig, getTimeScale, getDatatable, lensMultitable, @@ -49,6 +50,7 @@ export const setupExpressions = ( datatableColumn, tickLabelsConfig, axisTitlesVisibilityConfig, + axisColorsConfig, getDatatable(getFormatFactory(core)), getTimeScale(getTimeZoneFactory(core)), ].forEach((expressionFn) => expressions.registerFunction(expressionFn));