mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Lens] Allows the users to change the axis orientation (#106369)
* [Lens] Allows the users to change the axis orientation * Disable orientation if ticklabels are off Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
8d3007279e
commit
c656608d85
17 changed files with 381 additions and 10 deletions
|
@ -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';
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
},
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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', {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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 [
|
||||
|
|
|
@ -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(<AxisSettingsPopover {...props} />);
|
||||
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(<AxisSettingsPopover {...props} />);
|
||||
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(<AxisSettingsPopover {...props} areTickLabelsVisible={false} />);
|
||||
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(<AxisSettingsPopover {...props} />);
|
||||
expect(component.find('[data-test-subj="lnsshowEndzones"]').length).toBe(0);
|
||||
|
|
|
@ -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<AxisSettingsPopoverPro
|
|||
areTickLabelsVisible,
|
||||
areGridlinesVisible,
|
||||
isAxisTitleVisible,
|
||||
orientation,
|
||||
setOrientation,
|
||||
toggleAxisTitleVisibility,
|
||||
setEndzoneVisibility,
|
||||
endzonesVisible,
|
||||
|
@ -257,16 +294,6 @@ export const AxisSettingsPopover: React.FunctionComponent<AxisSettingsPopoverPro
|
|||
})}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSwitch
|
||||
compressed
|
||||
data-test-subj={`lnsshow${axis}AxisTickLabels`}
|
||||
label={i18n.translate('xpack.lens.xyChart.tickLabels', {
|
||||
defaultMessage: 'Tick labels',
|
||||
})}
|
||||
onChange={() => toggleTickLabelsVisibility(axis)}
|
||||
checked={areTickLabelsVisible}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSwitch
|
||||
compressed
|
||||
data-test-subj={`lnsshow${axis}AxisGridlines`}
|
||||
|
@ -276,6 +303,41 @@ export const AxisSettingsPopover: React.FunctionComponent<AxisSettingsPopoverPro
|
|||
onChange={() => toggleGridlinesVisibility(axis)}
|
||||
checked={areGridlinesVisible}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSwitch
|
||||
compressed
|
||||
data-test-subj={`lnsshow${axis}AxisTickLabels`}
|
||||
label={i18n.translate('xpack.lens.xyChart.tickLabels', {
|
||||
defaultMessage: 'Tick labels',
|
||||
})}
|
||||
onChange={() => toggleTickLabelsVisibility(axis)}
|
||||
checked={areTickLabelsVisible}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFormRow
|
||||
display="rowCompressed"
|
||||
fullWidth
|
||||
label={i18n.translate('xpack.lens.xyChart.axisOrientation.label', {
|
||||
defaultMessage: 'Orientation',
|
||||
})}
|
||||
>
|
||||
<EuiButtonGroup
|
||||
isFullWidth
|
||||
legend={i18n.translate('xpack.lens.xyChart.axisOrientation.label', {
|
||||
defaultMessage: 'Orientation',
|
||||
})}
|
||||
data-test-subj="lnsXY_axisOrientation_groups"
|
||||
name="axisOrientation"
|
||||
isDisabled={!areTickLabelsVisible}
|
||||
buttonSize="compressed"
|
||||
options={axisOrientationOptions}
|
||||
idSelected={axisOrientationOptions.find(({ value }) => value === orientation)!.id}
|
||||
onChange={(optionId) => {
|
||||
const newOrientation = axisOrientationOptions.find(({ id }) => id === optionId)!.value;
|
||||
setOrientation(axis, newOrientation);
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
{setEndzoneVisibility && (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
|
|
|
@ -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(<XYChart {...defaultProps} data={{ ...data }} args={{ ...args }} />);
|
||||
|
||||
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(<XYChart {...defaultProps} data={{ ...data }} args={{ ...args }} />);
|
||||
|
||||
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',
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
{
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue