mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] Fix axis title visibility bug (#134082)
* 🐛 fix title visibility bug * 🏷️ Fix type issues
This commit is contained in:
parent
32eb974887
commit
342e7a1783
7 changed files with 92 additions and 86 deletions
|
@ -287,7 +287,7 @@ export function XYChart({
|
|||
const getYAxesTitles = (axisSeries: Series[]) => {
|
||||
return axisSeries
|
||||
.map(({ layer, accessor }) => titles?.[layer]?.yTitles?.[accessor])
|
||||
.filter((name) => Boolean(name))[0];
|
||||
.find((name) => Boolean(name));
|
||||
};
|
||||
|
||||
const referenceLineLayers = getReferenceLayers(layers);
|
||||
|
|
|
@ -154,19 +154,17 @@ export const HeatmapToolbar = memo(
|
|||
<AxisTitleSettings
|
||||
axis="yLeft"
|
||||
axisTitle={state?.gridConfig.yTitle}
|
||||
updateTitleState={(value) =>
|
||||
updateTitleState={({ title, visible }) => {
|
||||
setState({
|
||||
...state,
|
||||
gridConfig: { ...state.gridConfig, yTitle: value },
|
||||
})
|
||||
}
|
||||
gridConfig: {
|
||||
...state.gridConfig,
|
||||
yTitle: title,
|
||||
isYAxisTitleVisible: visible,
|
||||
},
|
||||
});
|
||||
}}
|
||||
isAxisTitleVisible={state?.gridConfig.isYAxisTitleVisible}
|
||||
toggleAxisTitleVisibility={(_, checked) =>
|
||||
setState({
|
||||
...state,
|
||||
gridConfig: { ...state.gridConfig, isYAxisTitleVisible: checked },
|
||||
})
|
||||
}
|
||||
/>
|
||||
</ToolbarPopover>
|
||||
</TooltipWrapper>
|
||||
|
@ -189,19 +187,17 @@ export const HeatmapToolbar = memo(
|
|||
<AxisTitleSettings
|
||||
axis="x"
|
||||
axisTitle={state?.gridConfig.xTitle}
|
||||
updateTitleState={(value) =>
|
||||
updateTitleState={({ title, visible }) =>
|
||||
setState({
|
||||
...state,
|
||||
gridConfig: { ...state.gridConfig, xTitle: value },
|
||||
gridConfig: {
|
||||
...state.gridConfig,
|
||||
xTitle: title,
|
||||
isXAxisTitleVisible: visible,
|
||||
},
|
||||
})
|
||||
}
|
||||
isAxisTitleVisible={state?.gridConfig.isXAxisTitleVisible}
|
||||
toggleAxisTitleVisibility={(_, checked) =>
|
||||
setState({
|
||||
...state,
|
||||
gridConfig: { ...state.gridConfig, isXAxisTitleVisible: checked },
|
||||
})
|
||||
}
|
||||
/>
|
||||
</ToolbarPopover>
|
||||
</TooltipWrapper>
|
||||
|
|
|
@ -18,7 +18,6 @@ describe('Axes Title settings', () => {
|
|||
axisTitle: 'My custom X axis title',
|
||||
axis: 'x',
|
||||
isAxisTitleVisible: true,
|
||||
toggleAxisTitleVisibility: jest.fn(),
|
||||
updateTitleState: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
@ -39,6 +38,15 @@ describe('Axes Title settings', () => {
|
|||
expect(component.find('[data-test-subj="lnsxAxisTitle"]').last().prop('value')).toBe('');
|
||||
});
|
||||
|
||||
it('should set the mode to None if empty title is passed over and the visibility is set to false', () => {
|
||||
const component = mount(
|
||||
<AxisTitleSettings {...props} axisTitle={''} isAxisTitleVisible={false} />
|
||||
);
|
||||
expect(component.find('[data-test-subj="lnsxAxisTitle-select"]').last().prop('value')).toBe(
|
||||
'none'
|
||||
);
|
||||
});
|
||||
|
||||
it('should disable the input text if the switch is off', () => {
|
||||
const component = mount(<AxisTitleSettings {...props} isAxisTitleVisible={false} />);
|
||||
expect(component.find('[data-test-subj="lnsxAxisTitle"]').last().prop('disabled')).toBe(true);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { EuiSpacer, EuiFormRow } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { AxesSettingsConfig } from '@kbn/expression-xy-plugin/common';
|
||||
|
@ -23,17 +23,16 @@ export interface AxisTitleSettingsProps {
|
|||
*/
|
||||
axisTitle: string | undefined;
|
||||
/**
|
||||
* Callback to axis title change
|
||||
* Callback to axis title change for both title and visibility
|
||||
*/
|
||||
updateTitleState: (value: string) => void;
|
||||
updateTitleState: (
|
||||
state: { title?: string; visible: boolean },
|
||||
axis: AxesSettingsConfigKeys
|
||||
) => void;
|
||||
/**
|
||||
* Determines if the title visibility switch is on and the input text is disabled
|
||||
*/
|
||||
isAxisTitleVisible: boolean;
|
||||
/**
|
||||
* Toggles the axis title visibility
|
||||
*/
|
||||
toggleAxisTitleVisibility: (axis: AxesSettingsConfigKeys, checked: boolean) => void;
|
||||
}
|
||||
|
||||
export const AxisTitleSettings: React.FunctionComponent<AxisTitleSettingsProps> = ({
|
||||
|
@ -41,29 +40,34 @@ export const AxisTitleSettings: React.FunctionComponent<AxisTitleSettingsProps>
|
|||
axisTitle,
|
||||
updateTitleState,
|
||||
isAxisTitleVisible,
|
||||
toggleAxisTitleVisibility,
|
||||
}) => {
|
||||
const { inputValue: title, handleInputChange: onTitleChange } = useDebouncedValue<string>(
|
||||
const axisState = useMemo(
|
||||
() => ({
|
||||
title: axisTitle,
|
||||
visibility:
|
||||
!axisTitle && isAxisTitleVisible
|
||||
? 'auto'
|
||||
: isAxisTitleVisible
|
||||
? 'custom'
|
||||
: ('none' as LabelMode),
|
||||
}),
|
||||
[axisTitle, isAxisTitleVisible]
|
||||
);
|
||||
const onTitleChange = useCallback(
|
||||
({ title, visibility }: { title?: string; visibility: LabelMode }) =>
|
||||
updateTitleState({ title, visible: visibility !== 'none' }, axis),
|
||||
[axis, updateTitleState]
|
||||
);
|
||||
const { inputValue: localAxisState, handleInputChange: onLocalTitleChange } = useDebouncedValue<{
|
||||
title?: string;
|
||||
visibility: LabelMode;
|
||||
}>(
|
||||
{
|
||||
value: axisTitle || '',
|
||||
onChange: updateTitleState,
|
||||
value: axisState,
|
||||
onChange: onTitleChange,
|
||||
},
|
||||
{ allowFalsyValue: true }
|
||||
);
|
||||
const [titleMode, setTitleMode] = useState<LabelMode>(
|
||||
!title ? 'auto' : isAxisTitleVisible ? 'custom' : 'none'
|
||||
);
|
||||
|
||||
const updateVisibility = useCallback(
|
||||
(mode: LabelMode) => {
|
||||
const visible = mode !== 'none';
|
||||
if (visible !== isAxisTitleVisible) {
|
||||
toggleAxisTitleVisibility(axis, visible);
|
||||
}
|
||||
setTitleMode(mode);
|
||||
},
|
||||
[axis, isAxisTitleVisible, toggleAxisTitleVisibility]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -79,17 +83,14 @@ export const AxisTitleSettings: React.FunctionComponent<AxisTitleSettingsProps>
|
|||
defaultMessage: 'Axis title',
|
||||
})}
|
||||
dataTestSubj={`lns${axis}AxisTitle`}
|
||||
label={title || ''}
|
||||
mode={titleMode}
|
||||
label={localAxisState.title || ''}
|
||||
mode={localAxisState.visibility}
|
||||
placeholder={i18n.translate('xpack.lens.shared.overwriteAxisTitle', {
|
||||
defaultMessage: 'Overwrite axis title',
|
||||
})}
|
||||
hasAutoOption={true}
|
||||
handleChange={({ mode, label }) => {
|
||||
if (title !== label) {
|
||||
onTitleChange(label);
|
||||
}
|
||||
updateVisibility(mode);
|
||||
onLocalTitleChange({ title: label, visibility: mode });
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
|
|
@ -42,7 +42,6 @@ describe('Axes Settings', () => {
|
|||
areTickLabelsVisible: true,
|
||||
areGridlinesVisible: true,
|
||||
isAxisTitleVisible: true,
|
||||
toggleAxisTitleVisibility: jest.fn(),
|
||||
toggleTickLabelsVisibility: jest.fn(),
|
||||
toggleGridlinesVisibility: jest.fn(),
|
||||
hasBarOrAreaOnAxis: false,
|
||||
|
|
|
@ -53,7 +53,10 @@ export interface AxisSettingsPopoverProps {
|
|||
/**
|
||||
* Callback to axis title change
|
||||
*/
|
||||
updateTitleState: (value: string) => void;
|
||||
updateTitleState: (
|
||||
title: { title?: string; visible: boolean },
|
||||
axis: AxesSettingsConfigKeys
|
||||
) => void;
|
||||
/**
|
||||
* Determines if the popover is Disabled
|
||||
*/
|
||||
|
@ -86,10 +89,6 @@ export interface AxisSettingsPopoverProps {
|
|||
* Determines if the title visibility switch is on and the input text is disabled
|
||||
*/
|
||||
isAxisTitleVisible: boolean;
|
||||
/**
|
||||
* Toggles the axis title visibility
|
||||
*/
|
||||
toggleAxisTitleVisibility: (axis: AxesSettingsConfigKeys, checked: boolean) => void;
|
||||
/**
|
||||
* Set endzone visibility
|
||||
*/
|
||||
|
@ -219,7 +218,6 @@ export const AxisSettingsPopover: React.FunctionComponent<AxisSettingsPopoverPro
|
|||
isAxisTitleVisible,
|
||||
orientation,
|
||||
setOrientation,
|
||||
toggleAxisTitleVisibility,
|
||||
setEndzoneVisibility,
|
||||
endzonesVisible,
|
||||
extent,
|
||||
|
@ -271,7 +269,6 @@ export const AxisSettingsPopover: React.FunctionComponent<AxisSettingsPopoverPro
|
|||
axisTitle={axisTitle}
|
||||
updateTitleState={updateTitleState}
|
||||
isAxisTitleVisible={isAxisTitleVisible}
|
||||
toggleAxisTitleVisibility={toggleAxisTitleVisibility}
|
||||
/>
|
||||
<EuiFormRow
|
||||
display="columnCompressedSwitch"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { memo, useCallback, useState } from 'react';
|
||||
import React, { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Position, ScaleType } from '@elastic/charts';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
|
@ -113,6 +113,13 @@ function hasPercentageAxis(axisGroups: GroupsConfiguration, groupId: string, sta
|
|||
);
|
||||
}
|
||||
|
||||
const axisKeyToTitleMapping: Record<keyof AxesSettingsConfig, 'xTitle' | 'yTitle' | 'yRightTitle'> =
|
||||
{
|
||||
x: 'xTitle',
|
||||
yLeft: 'yTitle',
|
||||
yRight: 'yRightTitle',
|
||||
};
|
||||
|
||||
export const XyToolbar = memo(function XyToolbar(
|
||||
props: VisualizationToolbarProps<State> & { useLegacyTimeAxis?: boolean }
|
||||
) {
|
||||
|
@ -180,27 +187,28 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
});
|
||||
};
|
||||
|
||||
const axisTitlesVisibilitySettings = {
|
||||
x: state?.axisTitlesVisibilitySettings?.x ?? true,
|
||||
yLeft: state?.axisTitlesVisibilitySettings?.yLeft ?? true,
|
||||
yRight: state?.axisTitlesVisibilitySettings?.yRight ?? true,
|
||||
};
|
||||
const onAxisTitlesVisibilitySettingsChange = (
|
||||
axis: AxesSettingsConfigKeys,
|
||||
checked: boolean
|
||||
): void => {
|
||||
const newAxisTitlesVisibilitySettings = {
|
||||
...axisTitlesVisibilitySettings,
|
||||
...{
|
||||
[axis]: checked,
|
||||
},
|
||||
};
|
||||
setState({
|
||||
...state,
|
||||
axisTitlesVisibilitySettings: newAxisTitlesVisibilitySettings,
|
||||
});
|
||||
};
|
||||
const axisTitlesVisibilitySettings = useMemo(
|
||||
() => ({
|
||||
x: state?.axisTitlesVisibilitySettings?.x ?? true,
|
||||
yLeft: state?.axisTitlesVisibilitySettings?.yLeft ?? true,
|
||||
yRight: state?.axisTitlesVisibilitySettings?.yRight ?? true,
|
||||
}),
|
||||
[
|
||||
state?.axisTitlesVisibilitySettings?.x,
|
||||
state?.axisTitlesVisibilitySettings?.yLeft,
|
||||
state?.axisTitlesVisibilitySettings?.yRight,
|
||||
]
|
||||
);
|
||||
|
||||
const onTitleStateChange = useCallback(
|
||||
({ title, visible }: { title?: string; visible: boolean }, axis: keyof AxesSettingsConfig) =>
|
||||
setState({
|
||||
...state,
|
||||
[axisKeyToTitleMapping[axis]]: title,
|
||||
axisTitlesVisibilitySettings: { ...axisTitlesVisibilitySettings, [axis]: visible },
|
||||
}),
|
||||
[axisTitlesVisibilitySettings, setState, state]
|
||||
);
|
||||
const nonOrdinalXAxis = dataLayers.every(
|
||||
(layer) =>
|
||||
!layer.xAccessor ||
|
||||
|
@ -452,7 +460,7 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
axis="yLeft"
|
||||
layers={state?.layers}
|
||||
axisTitle={state?.yTitle}
|
||||
updateTitleState={(value) => setState({ ...state, yTitle: value })}
|
||||
updateTitleState={onTitleStateChange}
|
||||
areTickLabelsVisible={tickLabelsVisibilitySettings.yLeft}
|
||||
toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange}
|
||||
areGridlinesVisible={gridlinesVisibilitySettings.yLeft}
|
||||
|
@ -463,7 +471,6 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
orientation={labelsOrientation.yLeft}
|
||||
setOrientation={onLabelsOrientationChange}
|
||||
isAxisTitleVisible={axisTitlesVisibilitySettings.yLeft}
|
||||
toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange}
|
||||
extent={state?.yLeftExtent || { mode: 'full' }}
|
||||
setExtent={setLeftExtent}
|
||||
hasBarOrAreaOnAxis={hasBarOrAreaOnLeftAxis}
|
||||
|
@ -483,7 +490,7 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
axis="x"
|
||||
layers={state?.layers}
|
||||
axisTitle={state?.xTitle}
|
||||
updateTitleState={(value) => setState({ ...state, xTitle: value })}
|
||||
updateTitleState={onTitleStateChange}
|
||||
areTickLabelsVisible={tickLabelsVisibilitySettings.x}
|
||||
toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange}
|
||||
areGridlinesVisible={gridlinesVisibilitySettings.x}
|
||||
|
@ -491,7 +498,6 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
orientation={labelsOrientation.x}
|
||||
setOrientation={onLabelsOrientationChange}
|
||||
isAxisTitleVisible={axisTitlesVisibilitySettings.x}
|
||||
toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange}
|
||||
endzonesVisible={!state?.hideEndzones}
|
||||
setEndzoneVisibility={onChangeEndzoneVisiblity}
|
||||
hasBarOrAreaOnAxis={false}
|
||||
|
@ -522,7 +528,7 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
axis="yRight"
|
||||
layers={state?.layers}
|
||||
axisTitle={state?.yRightTitle}
|
||||
updateTitleState={(value) => setState({ ...state, yRightTitle: value })}
|
||||
updateTitleState={onTitleStateChange}
|
||||
areTickLabelsVisible={tickLabelsVisibilitySettings.yRight}
|
||||
toggleTickLabelsVisibility={onTickLabelsVisibilitySettingsChange}
|
||||
areGridlinesVisible={gridlinesVisibilitySettings.yRight}
|
||||
|
@ -535,7 +541,6 @@ export const XyToolbar = memo(function XyToolbar(
|
|||
setOrientation={onLabelsOrientationChange}
|
||||
hasPercentageAxis={hasPercentageAxis(axisGroups, 'right', state)}
|
||||
isAxisTitleVisible={axisTitlesVisibilitySettings.yRight}
|
||||
toggleAxisTitleVisibility={onAxisTitlesVisibilitySettingsChange}
|
||||
extent={state?.yRightExtent || { mode: 'full' }}
|
||||
setExtent={setRightExtent}
|
||||
hasBarOrAreaOnAxis={hasBarOrAreaOnRightAxis}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue