Skip to content

Commit

Permalink
[Lens] Add search to chart switcher (elastic#77631) (elastic#79709)
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 authored Oct 6, 2020
1 parent 2ba1a89 commit deb61f6
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ img.lnsChartSwitch__chartIcon { // sass-lint:disable-line no-qualifying-elements
// The large icons aren't square so max out the width to fill the height
width: 100%;
}

.lnsChartSwitch__search {
width: 4 * $euiSizeXXL;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ import {
EuiPopoverTitle,
EuiKeyPadMenu,
EuiKeyPadMenuItem,
EuiFieldSearch,
EuiFlexGroup,
EuiFlexItem,
EuiSelectableMessage,
} from '@elastic/eui';
import { flatten } from 'lodash';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { Visualization, FramePublicAPI, Datasource } from '../../../types';
import { Action } from '../state_management';
import { getSuggestions, switchToSuggestion, Suggestion } from '../suggestion_helpers';
Expand Down Expand Up @@ -173,6 +178,8 @@ export function ChartSwitch(props: Props) {
};
}

const [searchTerm, setSearchTerm] = useState('');

const visualizationTypes = useMemo(
() =>
flyoutOpen &&
Expand All @@ -184,17 +191,25 @@ export function ChartSwitch(props: Props) {
icon: t.icon,
}))
)
).map((visualizationType) => ({
...visualizationType,
selection: getSelection(visualizationType.visualizationId, visualizationType.id),
})),
)
.filter(
(visualizationType) =>
visualizationType.label.toLowerCase().includes(searchTerm.toLowerCase()) ||
(visualizationType.fullLabel &&
visualizationType.fullLabel.toLowerCase().includes(searchTerm.toLowerCase()))
)
.map((visualizationType) => ({
...visualizationType,
selection: getSelection(visualizationType.visualizationId, visualizationType.id),
})),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
flyoutOpen,
props.visualizationMap,
props.framePublicAPI,
props.visualizationId,
props.visualizationState,
searchTerm,
]
);

Expand All @@ -219,15 +234,30 @@ export function ChartSwitch(props: Props) {
anchorPosition="downLeft"
>
<EuiPopoverTitle>
{i18n.translate('xpack.lens.configPanel.selectVisualization', {
defaultMessage: 'Select a visualization',
})}
<EuiFlexGroup alignItems="center" responsive={false}>
<EuiFlexItem>
{i18n.translate('xpack.lens.configPanel.chartType', {
defaultMessage: 'Chart type',
})}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFieldSearch
compressed
fullWidth={false}
className="lnsChartSwitch__search"
value={searchTerm}
data-test-subj="lnsChartSwitchSearch"
onChange={(e) => setSearchTerm(e.target.value)}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopoverTitle>
<EuiKeyPadMenu>
{(visualizationTypes || []).map((v) => (
<EuiKeyPadMenuItem
key={`${v.visualizationId}:${v.id}`}
label={<span data-test-subj="visTypeTitle">{v.label}</span>}
title={v.fullLabel}
role="menuitem"
data-test-subj={`lnsChartSwitchPopover_${v.id}`}
onClick={() => commitSelection(v.selection)}
Expand All @@ -251,6 +281,17 @@ export function ChartSwitch(props: Props) {
</EuiKeyPadMenuItem>
))}
</EuiKeyPadMenu>
{searchTerm && (visualizationTypes || []).length === 0 && (
<EuiSelectableMessage>
<FormattedMessage
id="xpack.lens.chartSwitch.noResults"
defaultMessage="No results found for {term}."
values={{
term: <strong>{searchTerm}</strong>,
}}
/>
</EuiSelectableMessage>
)}
</EuiPopover>
);

Expand Down
16 changes: 16 additions & 0 deletions x-pack/plugins/lens/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,26 @@ export interface FramePublicAPI {
removeLayers: (layerIds: string[]) => void;
}

/**
* A visualization type advertised to the user in the chart switcher
*/
export interface VisualizationType {
/**
* Unique id of the visualization type within the visualization defining it
*/
id: string;
/**
* Icon used in the chart switcher
*/
icon: IconType;
/**
* Visible label used in the chart switcher and above the workspace panel in collapsed state
*/
label: string;
/**
* Optional label used in chart type search if chart switcher is expanded and for tooltips
*/
fullLabel?: string;
}

export interface Visualization<T = unknown> {
Expand Down
20 changes: 16 additions & 4 deletions x-pack/plugins/lens/public/xy_visualization/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@ export const visualizationTypes: VisualizationType[] = [
id: 'bar_horizontal',
icon: LensIconChartBarHorizontal,
label: i18n.translate('xpack.lens.xyVisualization.barHorizontalLabel', {
defaultMessage: 'H. Bar',
}),
fullLabel: i18n.translate('xpack.lens.xyVisualization.barHorizontalFullLabel', {
defaultMessage: 'Horizontal bar',
}),
},
Expand All @@ -440,22 +443,31 @@ export const visualizationTypes: VisualizationType[] = [
id: 'bar_percentage_stacked',
icon: LensIconChartBarPercentage,
label: i18n.translate('xpack.lens.xyVisualization.stackedPercentageBarLabel', {
defaultMessage: 'Bar percentage',
defaultMessage: 'Percentage bar',
}),
},
{
id: 'bar_horizontal_stacked',
icon: LensIconChartBarHorizontalStacked,
label: i18n.translate('xpack.lens.xyVisualization.stackedBarHorizontalLabel', {
defaultMessage: 'Stacked horizontal bar',
defaultMessage: 'H. Stacked bar',
}),
fullLabel: i18n.translate('xpack.lens.xyVisualization.stackedBarHorizontalFullLabel', {
defaultMessage: 'Horizontal stacked bar',
}),
},
{
id: 'bar_horizontal_percentage_stacked',
icon: LensIconChartBarHorizontalPercentage,
label: i18n.translate('xpack.lens.xyVisualization.stackedPercentageBarHorizontalLabel', {
defaultMessage: 'Horizontal bar percentage',
defaultMessage: 'H. Percentage bar',
}),
fullLabel: i18n.translate(
'xpack.lens.xyVisualization.stackedPercentageBarHorizontalFullLabel',
{
defaultMessage: 'Horizontal percentage bar',
}
),
},
{
id: 'area',
Expand All @@ -475,7 +487,7 @@ export const visualizationTypes: VisualizationType[] = [
id: 'area_percentage_stacked',
icon: LensIconChartAreaPercentage,
label: i18n.translate('xpack.lens.xyVisualization.stackedPercentageAreaLabel', {
defaultMessage: 'Area percentage',
defaultMessage: 'Percentage area',
}),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,38 @@ describe('xy_visualization', () => {
it('should show mixed xy chart when multilple series types', () => {
const desc = xyVisualization.getDescription(mixedState('bar', 'line'));

expect(desc.label).toEqual('Mixed XY chart');
expect(desc.label).toEqual('Mixed XY');
});

it('should show the preferredSeriesType if there are no layers', () => {
const desc = xyVisualization.getDescription(mixedState());

expect(desc.icon).toEqual(LensIconChartBar);
expect(desc.label).toEqual('Bar chart');
expect(desc.label).toEqual('Bar');
});

it('should show mixed horizontal bar chart when multiple horizontal bar types', () => {
const desc = xyVisualization.getDescription(
mixedState('bar_horizontal', 'bar_horizontal_stacked')
);

expect(desc.label).toEqual('Mixed horizontal bar chart');
expect(desc.label).toEqual('Mixed H. bar');
});

it('should show bar chart when bar only', () => {
const desc = xyVisualization.getDescription(mixedState('bar_horizontal', 'bar_horizontal'));

expect(desc.label).toEqual('Horizontal bar chart');
expect(desc.label).toEqual('H. Bar');
});

it('should show the chart description if not mixed', () => {
expect(xyVisualization.getDescription(mixedState('area')).label).toEqual('Area chart');
expect(xyVisualization.getDescription(mixedState('line')).label).toEqual('Line chart');
expect(xyVisualization.getDescription(mixedState('area')).label).toEqual('Area');
expect(xyVisualization.getDescription(mixedState('line')).label).toEqual('Line');
expect(xyVisualization.getDescription(mixedState('area_stacked')).label).toEqual(
'Stacked area chart'
'Stacked area'
);
expect(xyVisualization.getDescription(mixedState('bar_horizontal_stacked')).label).toEqual(
'Stacked horizontal bar chart'
'H. Stacked bar'
);
});
});
Expand Down
8 changes: 2 additions & 6 deletions x-pack/plugins/lens/public/xy_visualization/visualization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function getDescription(state?: State) {
return {
icon: LensIconChartBarHorizontal,
label: i18n.translate('xpack.lens.xyVisualization.mixedBarHorizontalLabel', {
defaultMessage: 'Mixed horizontal bar',
defaultMessage: 'Mixed H. bar',
}),
};
}
Expand Down Expand Up @@ -118,14 +118,10 @@ export const xyVisualization: Visualization<State> = {

getDescription(state) {
const { icon, label } = getDescription(state);
const chartLabel = i18n.translate('xpack.lens.xyVisualization.chartLabel', {
defaultMessage: '{label} chart',
values: { label },
});

return {
icon: icon || defaultIcon,
label: chartLabel,
label,
};
},

Expand Down
3 changes: 0 additions & 3 deletions x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -9659,15 +9659,12 @@
"xpack.lens.xySuggestions.unstackedChartTitle": "スタックが解除されました",
"xpack.lens.xySuggestions.yAxixConjunctionSign": " と ",
"xpack.lens.xyVisualization.areaLabel": "エリア",
"xpack.lens.xyVisualization.barHorizontalLabel": "横棒",
"xpack.lens.xyVisualization.barLabel": "バー",
"xpack.lens.xyVisualization.chartLabel": "{label} チャート",
"xpack.lens.xyVisualization.lineLabel": "折れ線",
"xpack.lens.xyVisualization.mixedBarHorizontalLabel": "ミックスされた横棒",
"xpack.lens.xyVisualization.mixedLabel": "ミックスされた XY",
"xpack.lens.xyVisualization.noDataLabel": "結果が見つかりませんでした",
"xpack.lens.xyVisualization.stackedAreaLabel": "スタックされたエリア",
"xpack.lens.xyVisualization.stackedBarHorizontalLabel": "スタックされた横棒",
"xpack.lens.xyVisualization.stackedBarLabel": "スタックされたバー",
"xpack.lens.xyVisualization.xyLabel": "XY",
"xpack.licenseMgmt.app.checkingPermissionsErrorMessage": "パーミッションの確認中にエラーが発生",
Expand Down
3 changes: 0 additions & 3 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -9665,15 +9665,12 @@
"xpack.lens.xySuggestions.unstackedChartTitle": "非堆叠",
"xpack.lens.xySuggestions.yAxixConjunctionSign": " &amp; ",
"xpack.lens.xyVisualization.areaLabel": "面积图",
"xpack.lens.xyVisualization.barHorizontalLabel": "水平条形图",
"xpack.lens.xyVisualization.barLabel": "条形图",
"xpack.lens.xyVisualization.chartLabel": "{label} 图表",
"xpack.lens.xyVisualization.lineLabel": "折线图",
"xpack.lens.xyVisualization.mixedBarHorizontalLabel": "混合水平条形图",
"xpack.lens.xyVisualization.mixedLabel": "混合 XY",
"xpack.lens.xyVisualization.noDataLabel": "找不到结果",
"xpack.lens.xyVisualization.stackedAreaLabel": "堆叠面积图",
"xpack.lens.xyVisualization.stackedBarHorizontalLabel": "堆叠水平条形图",
"xpack.lens.xyVisualization.stackedBarLabel": "堆叠条形图",
"xpack.lens.xyVisualization.xyLabel": "XY",
"xpack.licenseMgmt.app.checkingPermissionsErrorMessage": "检查权限时出错",
Expand Down

0 comments on commit deb61f6

Please sign in to comment.