diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/index.ts b/x-pack/plugins/lens/common/expressions/xy_chart/index.ts index 4d1125fa459a3..a6f6c715c0ed1 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/index.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/index.ts @@ -14,3 +14,4 @@ export * from './series_type'; export * from './tick_labels_config'; export * from './xy_args'; export * from './xy_chart'; +export * from './labels_orientation_config'; diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/labels_orientation_config.ts b/x-pack/plugins/lens/common/expressions/xy_chart/labels_orientation_config.ts new file mode 100644 index 0000000000000..773ce61a102f9 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/xy_chart/labels_orientation_config.ts @@ -0,0 +1,60 @@ +/* + * 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. + */ +import { i18n } from '@kbn/i18n'; +import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common'; + +export interface LabelsOrientationConfig { + x: number; + yLeft: number; + yRight: number; +} + +export type LabelsOrientationConfigResult = LabelsOrientationConfig & { + type: 'lens_xy_labelsOrientationConfig'; +}; + +export const labelsOrientationConfig: ExpressionFunctionDefinition< + 'lens_xy_labelsOrientationConfig', + null, + LabelsOrientationConfig, + LabelsOrientationConfigResult +> = { + name: 'lens_xy_labelsOrientationConfig', + aliases: [], + type: 'lens_xy_labelsOrientationConfig', + help: `Configure the xy chart's tick labels orientation`, + inputTypes: ['null'], + args: { + x: { + types: ['number'], + options: [0, -90, -45], + help: i18n.translate('xpack.lens.xyChart.xAxisLabelsOrientation.help', { + defaultMessage: 'Specifies the labels orientation of the x-axis.', + }), + }, + yLeft: { + types: ['number'], + options: [0, -90, -45], + help: i18n.translate('xpack.lens.xyChart.yLeftAxisLabelsOrientation.help', { + defaultMessage: 'Specifies the labels orientation of the left y-axis.', + }), + }, + yRight: { + types: ['number'], + options: [0, -90, -45], + help: i18n.translate('xpack.lens.xyChart.yRightAxisLabelsOrientation.help', { + defaultMessage: 'Specifies the labels orientation of the right y-axis.', + }), + }, + }, + fn: function fn(input: unknown, args: LabelsOrientationConfig) { + return { + type: 'lens_xy_labelsOrientationConfig', + ...args, + }; + }, +}; 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 3fcf2a187464d..fb794eda22dbe 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 @@ -11,6 +11,7 @@ import type { GridlinesConfigResult } from './grid_lines_config'; import type { LayerArgs } from './layer_config'; import type { LegendConfigResult } from './legend_config'; import type { TickLabelsConfigResult } from './tick_labels_config'; +import type { LabelsOrientationConfigResult } from './labels_orientation_config'; export type ValueLabelConfig = 'hide' | 'inside' | 'outside'; @@ -32,6 +33,7 @@ export interface XYArgs { axisTitlesVisibilitySettings?: AxisTitlesVisibilityConfigResult; tickLabelsVisibilitySettings?: TickLabelsConfigResult; gridlinesVisibilitySettings?: GridlinesConfigResult; + labelsOrientation?: LabelsOrientationConfigResult; curveType?: XYCurveType; fillOpacity?: number; hideEndzones?: boolean; 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 7fa26f4a2c25d..0e58105447689 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 @@ -97,6 +97,12 @@ export const xyChart: ExpressionFunctionDefinition< defaultMessage: 'Show x and y axes tick labels', }), }, + labelsOrientation: { + types: ['lens_xy_labelsOrientationConfig'], + help: i18n.translate('xpack.lens.xyChart.labelsOrientation.help', { + defaultMessage: 'Defines the rotation of the axis labels', + }), + }, gridlinesVisibilitySettings: { types: ['lens_xy_gridlinesConfig'], help: i18n.translate('xpack.lens.xyChart.gridlinesSettings.help', { 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 26fe4dc72921d..54bb3efd75b39 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 @@ -51,6 +51,7 @@ exports[`xy_expression XYChart component it renders area 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -81,6 +82,7 @@ exports[`xy_expression XYChart component it renders area 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -266,6 +268,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -296,6 +299,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -493,6 +497,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -523,6 +528,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -720,6 +726,7 @@ exports[`xy_expression XYChart component it renders line 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -750,6 +757,7 @@ exports[`xy_expression XYChart component it renders line 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -935,6 +943,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -965,6 +974,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -1158,6 +1168,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -1188,6 +1199,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } @@ -1393,6 +1405,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = "visible": true, }, "tickLabel": Object { + "rotation": 0, "visible": true, }, } @@ -1423,6 +1436,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = "visible": true, }, "tickLabel": Object { + "rotation": -90, "visible": false, }, } 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 bcf54c6696ee0..3bd0e9354c158 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 @@ -64,6 +64,28 @@ Object { "hideEndzones": Array [ true, ], + "labelsOrientation": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "x": Array [ + 0, + ], + "yLeft": Array [ + -90, + ], + "yRight": Array [ + -45, + ], + }, + "function": "lens_xy_labelsOrientationConfig", + "type": "function", + }, + ], + "type": "expression", + }, + ], "layers": Array [ Object { "chain": Array [ diff --git a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.test.tsx b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.test.tsx index 2e5fdf8493e24..7609c534711d0 100644 --- a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.test.tsx @@ -34,6 +34,8 @@ describe('Axes Settings', () => { toggleGridlinesVisibility: jest.fn(), hasBarOrAreaOnAxis: false, hasPercentageAxis: false, + orientation: 0, + setOrientation: jest.fn(), }; }); @@ -82,6 +84,28 @@ describe('Axes Settings', () => { ); }); + it('has selected the horizontal option on the orientation group', () => { + const component = shallow(); + expect( + component.find('[data-test-subj="lnsXY_axisOrientation_groups"]').prop('idSelected') + ).toEqual('xy_axis_orientation_horizontal'); + }); + + it('should have called the setOrientation function on orientation button group change', () => { + const component = shallow(); + component + .find('[data-test-subj="lnsXY_axisOrientation_groups"]') + .simulate('change', 'xy_axis_orientation_angled'); + expect(props.setOrientation).toHaveBeenCalled(); + }); + + it('should disable the orientation group if the tickLabels are set to not visible', () => { + const component = shallow(); + expect( + component.find('[data-test-subj="lnsXY_axisOrientation_groups"]').prop('isDisabled') + ).toEqual(true); + }); + it('hides the endzone visibility flag if no setter is passed in', () => { const component = shallow(); expect(component.find('[data-test-subj="lnsshowEndzones"]').length).toBe(0); diff --git a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx index 52098ab92cad6..2285cd1a7a43a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/axis_settings_popover.tsx @@ -57,6 +57,14 @@ export interface AxisSettingsPopoverProps { * Determines if the ticklabels of the axis are visible */ areTickLabelsVisible: boolean; + /** + * Determines the axis labels orientation + */ + orientation: number; + /** + * Callback on orientation option change + */ + setOrientation: (axis: AxesSettingsConfigKeys, orientation: number) => void; /** * Toggles the axis tickLabels visibility */ @@ -151,6 +159,33 @@ const popoverConfig = ( }; } }; +const axisOrientationOptions: Array<{ + id: string; + value: 0 | -90 | -45; + label: string; +}> = [ + { + id: 'xy_axis_orientation_horizontal', + value: 0, + label: i18n.translate('xpack.lens.xyChart.axisOrientation.horizontal', { + defaultMessage: 'Horizontal', + }), + }, + { + id: 'xy_axis_orientation_vertical', + value: -90, + label: i18n.translate('xpack.lens.xyChart.axisOrientation.vertical', { + defaultMessage: 'Vertical', + }), + }, + { + id: 'xy_axis_orientation_angled', + value: -45, + label: i18n.translate('xpack.lens.xyChart.axisOrientation.angled', { + defaultMessage: 'Angled', + }), + }, +]; const noop = () => {}; const idPrefix = htmlIdGenerator()(); @@ -165,6 +200,8 @@ export const AxisSettingsPopover: React.FunctionComponent + toggleGridlinesVisibility(axis)} + checked={areGridlinesVisible} + /> + toggleTickLabelsVisibility(axis)} checked={areTickLabelsVisible} /> - - + toggleGridlinesVisibility(axis)} - checked={areGridlinesVisible} - /> + > + value === orientation)!.id} + onChange={(optionId) => { + const newOrientation = axisOrientationOptions.find(({ id }) => id === optionId)!.value; + setOrientation(axis, newOrientation); + }} + /> + {setEndzoneVisibility && ( <> 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 3a28f137f93bd..291b536210de5 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -34,6 +34,8 @@ import { LayerArgs, AxesSettingsConfig, XYChartProps, + labelsOrientationConfig, + LabelsOrientationConfig, } from '../../common/expressions'; import { Datatable, DatatableRow } from '../../../../../src/plugins/expressions/public'; import React from 'react'; @@ -276,6 +278,12 @@ const createArgsWithLayers = (layers: LayerArgs[] = [sampleLayer]): XYArgs => ({ yLeft: false, yRight: false, }, + labelsOrientation: { + type: 'lens_xy_labelsOrientationConfig', + x: 0, + yLeft: -90, + yRight: -45, + }, gridlinesVisibilitySettings: { type: 'lens_xy_gridlinesConfig', x: true, @@ -381,6 +389,21 @@ describe('xy_expression', () => { }); }); + test('labelsOrientationConfig produces the correct arguments', () => { + const args: LabelsOrientationConfig = { + x: 0, + yLeft: -90, + yRight: -45, + }; + + const result = labelsOrientationConfig.fn(null, args, createMockExecutionContext()); + + expect(result).toEqual({ + type: 'lens_xy_labelsOrientationConfig', + ...args, + }); + }); + describe('xyChart', () => { test('it renders with the specified data and args', () => { const { data, args } = sampleArgs(); @@ -1982,6 +2005,27 @@ describe('xy_expression', () => { }); }); + test('it should set the tickLabel orientation on the x axis', () => { + const { data, args } = sampleArgs(); + + args.labelsOrientation = { + x: -45, + yLeft: 0, + yRight: -90, + type: 'lens_xy_labelsOrientationConfig', + }; + + const instance = shallow(); + + const axisStyle = instance.find(Axis).first().prop('style'); + + expect(axisStyle).toMatchObject({ + tickLabel: { + rotation: -45, + }, + }); + }); + test('it should set the tickLabel visibility on the y axis if the tick labels is shown', () => { const { data, args } = sampleArgs(); @@ -2003,6 +2047,27 @@ describe('xy_expression', () => { }); }); + test('it should set the tickLabel orientation on the y axis', () => { + const { data, args } = sampleArgs(); + + args.labelsOrientation = { + x: -45, + yLeft: -90, + yRight: -90, + type: 'lens_xy_labelsOrientationConfig', + }; + + const instance = shallow(); + + const axisStyle = instance.find(Axis).at(1).prop('style'); + + expect(axisStyle).toMatchObject({ + tickLabel: { + rotation: -90, + }, + }); + }); + test('it should remove invalid rows', () => { const data: LensMultiTable = { type: 'lens_multitable', @@ -2052,6 +2117,12 @@ describe('xy_expression', () => { yLeft: false, yRight: false, }, + labelsOrientation: { + type: 'lens_xy_labelsOrientationConfig', + x: 0, + yLeft: 0, + yRight: 0, + }, yLeftExtent: { mode: 'full', type: 'lens_xy_axisExtentConfig', @@ -2134,6 +2205,12 @@ describe('xy_expression', () => { yLeft: false, yRight: false, }, + labelsOrientation: { + type: 'lens_xy_labelsOrientationConfig', + x: 0, + yLeft: 0, + yRight: 0, + }, yLeftExtent: { mode: 'full', type: 'lens_xy_axisExtentConfig', @@ -2202,6 +2279,12 @@ describe('xy_expression', () => { yLeft: false, yRight: false, }, + labelsOrientation: { + type: 'lens_xy_labelsOrientationConfig', + x: 0, + yLeft: 0, + yRight: 0, + }, yLeftExtent: { mode: 'full', type: 'lens_xy_axisExtentConfig', diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 4cd63c5747e87..56867c625bb6f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -80,6 +80,7 @@ export { axisExtentConfig, layerConfig, xyChart, + labelsOrientationConfig, } from '../../common/expressions'; export type XYChartRenderProps = XYChartProps & { @@ -287,6 +288,12 @@ export function XYChart({ yRight: true, }; + const labelsOrientation = args.labelsOrientation || { + x: 0, + yLeft: 0, + yRight: 0, + }; + const filteredBarLayers = filteredLayers.filter((layer) => layer.seriesType.includes('bar')); const chartHasMoreThanOneBarSeries = @@ -328,6 +335,10 @@ export function XYChart({ groupId === 'right' ? tickLabelsVisibilitySettings?.yRight : tickLabelsVisibilitySettings?.yLeft, + rotation: + groupId === 'right' + ? args.labelsOrientation?.yRight || 0 + : args.labelsOrientation?.yLeft || 0, }, axisTitle: { visible: @@ -526,6 +537,7 @@ export function XYChart({ style={{ tickLabel: { visible: tickLabelsVisibilitySettings?.x, + rotation: labelsOrientation?.x, }, axisTitle: { visible: axisTitlesVisibilitySettings.x, diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts index de9ecd0b694e4..d0f6666f7cd93 100644 --- a/x-pack/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/plugins/lens/public/xy_visualization/index.ts @@ -35,6 +35,7 @@ export class XyVisualization { gridlinesConfig, axisTitlesVisibilityConfig, axisExtentConfig, + labelsOrientationConfig, layerConfig, xyChart, getXyChartRenderer, @@ -46,6 +47,7 @@ export class XyVisualization { expressions.registerFunction(() => yAxisConfig); expressions.registerFunction(() => tickLabelsConfig); expressions.registerFunction(() => axisExtentConfig); + expressions.registerFunction(() => labelsOrientationConfig); expressions.registerFunction(() => gridlinesConfig); expressions.registerFunction(() => axisTitlesVisibilityConfig); expressions.registerFunction(() => layerConfig); diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts index a7270bdf8f331..f43b633f4a716 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts @@ -50,6 +50,11 @@ describe('#toExpression', () => { preferredSeriesType: 'bar', fittingFunction: 'Carry', tickLabelsVisibilitySettings: { x: false, yLeft: true, yRight: true }, + labelsOrientation: { + x: 0, + yLeft: -90, + yRight: -45, + }, gridlinesVisibilitySettings: { x: false, yLeft: true, yRight: true }, hideEndzones: true, yRightExtent: { @@ -229,6 +234,31 @@ describe('#toExpression', () => { }); }); + it('should default the tick labels orientation settings to 0', () => { + const expression = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + valueLabels: 'hide', + preferredSeriesType: 'bar', + layers: [ + { + layerId: 'first', + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], + }, + ], + }, + frame.datasourceLayers + ) as Ast; + expect((expression.chain[0].arguments.labelsOrientation[0] as Ast).chain[0].arguments).toEqual({ + x: [0], + yLeft: [0], + yRight: [0], + }); + }); + it('should default the gridlines visibility settings to true', () => { 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 b588cd5592a43..dfad8334ab76a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -255,6 +255,22 @@ export const buildExpression = ( ], }, ], + labelsOrientation: [ + { + type: 'expression', + chain: [ + { + type: 'function', + function: 'lens_xy_labelsOrientationConfig', + arguments: { + x: [state?.labelsOrientation?.x ?? 0], + yLeft: [state?.labelsOrientation?.yLeft ?? 0], + yRight: [state?.labelsOrientation?.yRight ?? 0], + }, + }, + ], + }, + ], valueLabels: [state?.valueLabels || 'hide'], hideEndzones: [state?.hideEndzones || false], valuesInLegend: [state?.valuesInLegend || false], diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index dcc147b4170a0..9d32c2f71c530 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -27,6 +27,7 @@ import { XYCurveType, AxesSettingsConfig, FittingFunction, + LabelsOrientationConfig, } from '../../common/expressions'; // Persisted parts of the state @@ -44,6 +45,7 @@ export interface XYState { axisTitlesVisibilitySettings?: AxesSettingsConfig; tickLabelsVisibilitySettings?: AxesSettingsConfig; gridlinesVisibilitySettings?: AxesSettingsConfig; + labelsOrientation?: LabelsOrientationConfig; curveType?: XYCurveType; fillOpacity?: number; hideEndzones?: boolean; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 061d0cbc4b4b5..129f2df895ef2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -221,6 +221,25 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp }); }; + const labelsOrientation = { + x: state?.labelsOrientation?.x ?? 0, + yLeft: state?.labelsOrientation?.yLeft ?? 0, + yRight: state?.labelsOrientation?.yRight ?? 0, + }; + + const onLabelsOrientationChange = (axis: AxesSettingsConfigKeys, orientation: number): void => { + const newLabelsOrientation = { + ...labelsOrientation, + ...{ + [axis]: orientation, + }, + }; + setState({ + ...state, + labelsOrientation: newLabelsOrientation, + }); + }; + const axisTitlesVisibilitySettings = { x: state?.axisTitlesVisibilitySettings?.x ?? true, yLeft: state?.axisTitlesVisibilitySettings?.yLeft ?? true, @@ -426,6 +445,8 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp isDisabled={ Object.keys(axisGroups.find((group) => group.groupId === 'left') || {}).length === 0 } + orientation={labelsOrientation.yLeft} + setOrientation={onLabelsOrientationChange} isAxisTitleVisible={axisTitlesVisibilitySettings.yLeft} toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange} extent={state?.yLeftExtent || { mode: 'full' }} @@ -444,6 +465,8 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange} areGridlinesVisible={gridlinesVisibilitySettings.x} toggleGridlinesVisibility={onGridlinesVisibilitySettingsChange} + orientation={labelsOrientation.x} + setOrientation={onLabelsOrientationChange} isAxisTitleVisible={axisTitlesVisibilitySettings.x} toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange} endzonesVisible={!state?.hideEndzones} @@ -478,6 +501,8 @@ export const XyToolbar = memo(function XyToolbar(props: VisualizationToolbarProp Object.keys(axisGroups.find((group) => group.groupId === 'right') || {}).length === 0 } + orientation={labelsOrientation.yRight} + setOrientation={onLabelsOrientationChange} hasPercentageAxis={hasPercentageAxis(axisGroups, 'right', state)} isAxisTitleVisible={axisTitlesVisibilitySettings.yRight} toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange} 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 277ca4467aeda..87165d64625e7 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 @@ -633,6 +633,7 @@ describe('xy_suggestions', () => { axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, + labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, preferredSeriesType: 'bar', layers: [ { @@ -675,6 +676,7 @@ describe('xy_suggestions', () => { axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, + labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, layers: [ { accessors: ['price', 'quantity'], @@ -790,6 +792,7 @@ describe('xy_suggestions', () => { axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, + labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, layers: [ { accessors: ['price', 'quantity'], @@ -833,6 +836,7 @@ describe('xy_suggestions', () => { axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, + labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, layers: [ { accessors: ['price'], @@ -877,6 +881,7 @@ describe('xy_suggestions', () => { axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false }, + labelsOrientation: { x: 0, yLeft: -45, yRight: -45 }, layers: [ { accessors: ['price', 'quantity'], 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 893bd5fd04ee4..dfa0646404388 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -543,6 +543,11 @@ function buildSuggestion({ yLeft: true, yRight: true, }, + labelsOrientation: currentState?.labelsOrientation || { + x: 0, + yLeft: 0, + yRight: 0, + }, gridlinesVisibilitySettings: currentState?.gridlinesVisibilitySettings || { x: true, yLeft: true,