Skip to content

Commit

Permalink
[TSVB] Long legend values support (#108023)
Browse files Browse the repository at this point in the history
* [TSVB] Supports legends with long values

* Add a unit test

* Design optimization

* Revert changes

* Add the missing prop type

* Ensure that the limits are respected

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
stratoula and kibanamachine committed Aug 19, 2021
1 parent 544c41e commit fe08d0a
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 63 deletions.
2 changes: 2 additions & 0 deletions src/plugins/vis_type_timeseries/common/types/panel_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ export interface Panel {
series: Series[];
show_grid: number;
show_legend: number;
truncate_legend?: number;
max_lines_legend?: number;
time_field?: string;
time_range_mode?: string;
tooltip_mode?: TOOLTIP_MODES;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { shallowWithIntl as shallow } from '@kbn/test/jest';

jest.mock('../lib/get_default_query_language', () => ({
getDefaultQueryLanguage: () => 'kuery',
}));

import { TimeseriesPanelConfig } from './timeseries';
import { PanelConfigProps } from './types';

describe('TimeseriesPanelConfig', () => {
it('sets the number input to the given value', () => {
const props = ({
fields: {},
model: {
max_lines_legend: 2,
},
onChange: jest.fn(),
} as unknown) as PanelConfigProps;
const wrapper = shallow(<TimeseriesPanelConfig {...props} />);
wrapper.instance().setState({ selectedTab: 'options' });
expect(
wrapper.find('[data-test-subj="timeSeriesEditorDataMaxLegendLines"]').prop('value')
).toEqual(2);
});

it('switches on the truncate legend switch if the prop is set to 1 ', () => {
const props = ({
fields: {},
model: {
max_lines_legend: 2,
truncate_legend: 1,
},
onChange: jest.fn(),
} as unknown) as PanelConfigProps;
const wrapper = shallow(<TimeseriesPanelConfig {...props} />);
wrapper.instance().setState({ selectedTab: 'options' });
expect(
wrapper.find('[data-test-subj="timeSeriesEditorDataTruncateLegendSwitch"]').prop('value')
).toEqual(1);
});

it('switches off the truncate legend switch if the prop is set to 0', () => {
const props = ({
fields: {},
model: {
max_lines_legend: 2,
truncate_legend: 0,
},
onChange: jest.fn(),
} as unknown) as PanelConfigProps;
const wrapper = shallow(<TimeseriesPanelConfig {...props} />);
wrapper.instance().setState({ selectedTab: 'options' });
expect(
wrapper.find('[data-test-subj="timeSeriesEditorDataTruncateLegendSwitch"]').prop('value')
).toEqual(0);
});

it('disables the max lines number input if the truncate legend switch is off', () => {
const props = ({
fields: {},
model: {
max_lines_legend: 2,
truncate_legend: 0,
},
onChange: jest.fn(),
} as unknown) as PanelConfigProps;
const wrapper = shallow(<TimeseriesPanelConfig {...props} />);
wrapper.instance().setState({ selectedTab: 'options' });
expect(
wrapper.find('[data-test-subj="timeSeriesEditorDataMaxLegendLines"]').prop('disabled')
).toEqual(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
EuiFieldText,
EuiTitle,
EuiHorizontalRule,
EuiFieldNumber,
} from '@elastic/eui';

// @ts-expect-error not typed yet
Expand Down Expand Up @@ -102,6 +103,9 @@ const legendPositionOptions = [
},
];

const MAX_TRUNCATE_LINES = 5;
const MIN_TRUNCATE_LINES = 1;

export class TimeseriesPanelConfig extends Component<
PanelConfigProps,
{ selectedTab: PANEL_CONFIG_TABS }
Expand Down Expand Up @@ -344,71 +348,117 @@ export class TimeseriesPanelConfig extends Component<
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<ColorPicker
onChange={this.props.onChange}
name="background_color"
value={model.background_color}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormRow
label={i18n.translate('visTypeTimeseries.timeseries.optionsTab.showLegendLabel', {
defaultMessage: 'Show legend?',
})}
>
<YesNo
value={model.show_legend}
name="show_legend"
onChange={this.props.onChange}
<EuiFormLabel>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.displayGridLabel"
defaultMessage="Display grid"
/>
</EuiFormRow>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormLabel htmlFor={htmlId('legendPos')}>
<YesNo value={model.show_grid} name="show_grid" onChange={this.props.onChange} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormLabel>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.legendPositionLabel"
defaultMessage="Legend position"
id="visTypeTimeseries.timeseries.optionsTab.tooltipMode"
defaultMessage="Tooltip"
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiComboBox
isClearable={false}
id={htmlId('legendPos')}
options={legendPositionOptions}
selectedOptions={selectedLegendPosOption ? [selectedLegendPosOption] : []}
onChange={handleSelectChange('legend_position')}
id={htmlId('tooltipMode')}
options={tooltipModeOptions}
selectedOptions={selectedTooltipMode ? [selectedTooltipMode] : []}
onChange={handleSelectChange('tooltip_mode')}
singleSelection={{ asPlainText: true }}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup responsive={false} wrap={true} alignItems="center">
<EuiFlexItem grow={false}>
<EuiFormRow
label={i18n.translate(
'visTypeTimeseries.timeseries.optionsTab.displayGridLabel',
{
defaultMessage: 'Display grid',
}
)}
>
<YesNo value={model.show_grid} name="show_grid" onChange={this.props.onChange} />
</EuiFormRow>
<EuiFormLabel>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.showLegendLabel"
defaultMessage="Show legend?"
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<YesNo
value={model.show_legend}
name="show_legend"
onChange={this.props.onChange}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormLabel>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.tooltipMode"
defaultMessage="Tooltip"
id="visTypeTimeseries.timeseries.optionsTab.truncateLegendLabel"
defaultMessage="Truncate legend?"
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<YesNo
value={model.truncate_legend}
name="truncate_legend"
onChange={this.props.onChange}
data-test-subj="timeSeriesEditorDataTruncateLegendSwitch"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormLabel>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.maxLinesLabel"
defaultMessage="Maximum legend lines"
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFieldNumber
data-test-subj="timeSeriesEditorDataMaxLegendLines"
value={model.max_lines_legend}
min={MIN_TRUNCATE_LINES}
max={MAX_TRUNCATE_LINES}
compressed
disabled={!Boolean(model.truncate_legend)}
onChange={(e) => {
const val = Number(e.target.value);
this.props.onChange({
max_lines_legend: Math.min(
MAX_TRUNCATE_LINES,
Math.max(val, MIN_TRUNCATE_LINES)
),
});
}}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormLabel htmlFor={htmlId('legendPos')}>
<FormattedMessage
id="visTypeTimeseries.timeseries.optionsTab.legendPositionLabel"
defaultMessage="Legend position"
/>
</EuiFormLabel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiComboBox
isClearable={false}
id={htmlId('tooltipMode')}
options={tooltipModeOptions}
selectedOptions={selectedTooltipMode ? [selectedTooltipMode] : []}
onChange={handleSelectChange('tooltip_mode')}
id={htmlId('legendPos')}
options={legendPositionOptions}
selectedOptions={selectedLegendPosOption ? [selectedLegendPosOption] : []}
onChange={handleSelectChange('legend_position')}
singleSelection={{ asPlainText: true }}
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ class TimeseriesVisualization extends Component {
showGrid={Boolean(model.show_grid)}
legend={Boolean(model.show_legend)}
legendPosition={model.legend_position}
truncateLegend={Boolean(model.truncate_legend)}
maxLegendLines={model.max_lines_legend}
tooltipMode={model.tooltip_mode}
xAxisFormatter={this.xAxisFormatter(interval)}
annotations={this.prepareAnnotations()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export const TimeSeries = ({
showGrid,
legend,
legendPosition,
truncateLegend,
maxLegendLines,
tooltipMode,
series,
yAxis,
Expand Down Expand Up @@ -172,6 +174,9 @@ export const TimeSeries = ({
background: {
color: backgroundColor,
},
legend: {
labelOptions: { maxLines: truncateLegend ? maxLegendLines ?? 1 : 0 },
},
},
chartTheme,
]}
Expand Down Expand Up @@ -216,6 +221,7 @@ export const TimeSeries = ({
lines,
data,
hideInLegend,
truncateLegend,
xScaleType,
yScaleType,
groupId,
Expand Down Expand Up @@ -249,6 +255,7 @@ export const TimeSeries = ({
name={getValueOrEmpty(seriesName)}
data={data}
hideInLegend={hideInLegend}
truncateLegend={truncateLegend}
bars={bars}
color={finalColor}
stackAccessors={stackAccessors}
Expand All @@ -274,6 +281,7 @@ export const TimeSeries = ({
name={getValueOrEmpty(seriesName)}
data={data}
hideInLegend={hideInLegend}
truncateLegend={truncateLegend}
lines={lines}
color={finalColor}
stackAccessors={stackAccessors}
Expand Down Expand Up @@ -336,6 +344,8 @@ TimeSeries.propTypes = {
showGrid: PropTypes.bool,
legend: PropTypes.bool,
legendPosition: PropTypes.string,
truncateLegend: PropTypes.bool,
maxLegendLines: PropTypes.number,
series: PropTypes.array,
yAxis: PropTypes.array,
onBrush: PropTypes.func,
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/vis_type_timeseries/public/metrics_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export const metricsVisDefinition: VisTypeDefinition<
axis_formatter: 'number',
axis_scale: 'normal',
show_legend: 1,
truncate_legend: 1,
max_lines_legend: 1,
show_grid: 1,
tooltip_mode: TOOLTIP_MODES.SHOW_ALL,
drop_last_bucket: 0,
Expand Down
27 changes: 0 additions & 27 deletions x-pack/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,3 @@
# yarn lockfile v1


"@kbn/interpreter@link:../packages/kbn-interpreter":
version "0.0.0"
uid ""

"@kbn/optimizer@link:../packages/kbn-optimizer":
version "0.0.0"
uid ""

"@kbn/plugin-helpers@link:../packages/kbn-plugin-helpers":
version "0.0.0"
uid ""

"@kbn/storybook@link:../packages/kbn-storybook":
version "0.0.0"
uid ""

"@kbn/test@link:../packages/kbn-test":
version "0.0.0"
uid ""

"@kbn/ui-framework@link:../packages/kbn-ui-framework":
version "0.0.0"
uid ""

"@kbn/ui-shared-deps@link:../packages/kbn-ui-shared-deps":
version "0.0.0"
uid ""

0 comments on commit fe08d0a

Please sign in to comment.