mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[XY, Pie] Long legend values support (#108365)
* [XY, Pie] Long legend values support * Update vislib snapshots * Fix truncate labels to work only for slice labels positioned outside the chart * Address PR comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
cb0ce59376
commit
4419efcbd0
33 changed files with 285 additions and 11 deletions
|
@ -16,3 +16,4 @@ export { RangeOption } from './range';
|
|||
export { RequiredNumberInputOption } from './required_number_input';
|
||||
export { TextInputOption } from './text_input';
|
||||
export { PercentageModeOption } from './percentage_mode';
|
||||
export { LongLegendOptions } from './long_legend_options';
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 { mountWithIntl } from '@kbn/test/jest';
|
||||
import { LongLegendOptions, LongLegendOptionsProps } from './long_legend_options';
|
||||
import { EuiFieldNumber } from '@elastic/eui';
|
||||
|
||||
describe('LongLegendOptions', () => {
|
||||
let props: LongLegendOptionsProps;
|
||||
let component;
|
||||
beforeAll(() => {
|
||||
props = {
|
||||
truncateLegend: true,
|
||||
setValue: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
it('renders the EuiFieldNumber', () => {
|
||||
component = mountWithIntl(<LongLegendOptions {...props} />);
|
||||
expect(component.find(EuiFieldNumber).length).toBe(1);
|
||||
});
|
||||
|
||||
it('should call setValue when value is changes in the number input', () => {
|
||||
component = mountWithIntl(<LongLegendOptions {...props} />);
|
||||
const numberField = component.find(EuiFieldNumber);
|
||||
numberField.props().onChange!(({
|
||||
target: {
|
||||
value: 3,
|
||||
},
|
||||
} as unknown) as React.ChangeEvent<HTMLInputElement>);
|
||||
|
||||
expect(props.setValue).toHaveBeenCalledWith('maxLegendLines', 3);
|
||||
});
|
||||
|
||||
it('input number should be disabled when truncate is false', () => {
|
||||
props.truncateLegend = false;
|
||||
component = mountWithIntl(<LongLegendOptions {...props} />);
|
||||
const numberField = component.find(EuiFieldNumber);
|
||||
|
||||
expect(numberField.props().disabled).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiFieldNumber, EuiFormRow } from '@elastic/eui';
|
||||
import { SwitchOption } from './switch';
|
||||
|
||||
const MAX_TRUNCATE_LINES = 5;
|
||||
const MIN_TRUNCATE_LINES = 1;
|
||||
|
||||
export interface LongLegendOptionsProps {
|
||||
setValue: (paramName: 'maxLegendLines' | 'truncateLegend', value: boolean | number) => void;
|
||||
truncateLegend: boolean;
|
||||
maxLegendLines?: number;
|
||||
'data-test-subj'?: string;
|
||||
}
|
||||
|
||||
function LongLegendOptions({
|
||||
'data-test-subj': dataTestSubj,
|
||||
setValue,
|
||||
truncateLegend,
|
||||
maxLegendLines,
|
||||
}: LongLegendOptionsProps) {
|
||||
return (
|
||||
<>
|
||||
<SwitchOption
|
||||
data-test-subj={dataTestSubj}
|
||||
label={i18n.translate('visDefaultEditor.options.longLegends.truncateLegendTextLabel', {
|
||||
defaultMessage: 'Truncate legend text',
|
||||
})}
|
||||
paramName="truncateLegend"
|
||||
value={truncateLegend}
|
||||
setValue={setValue}
|
||||
/>
|
||||
<EuiFormRow
|
||||
fullWidth
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="visDefaultEditor.options.longLegends.maxLegendLinesLabel"
|
||||
defaultMessage="Maximum legend lines"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
data-test-subj="timeSeriesEditorDataMaxLegendLines"
|
||||
value={maxLegendLines}
|
||||
min={MIN_TRUNCATE_LINES}
|
||||
max={MAX_TRUNCATE_LINES}
|
||||
fullWidth
|
||||
disabled={!Boolean(truncateLegend)}
|
||||
onChange={(e) => {
|
||||
const val = Number(e.target.value);
|
||||
setValue(
|
||||
'maxLegendLines',
|
||||
Math.min(MAX_TRUNCATE_LINES, Math.max(val, MIN_TRUNCATE_LINES))
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export { LongLegendOptions };
|
|
@ -57,6 +57,7 @@ Object {
|
|||
"valuesFormat": "percent",
|
||||
},
|
||||
"legendPosition": "right",
|
||||
"maxLegendLines": true,
|
||||
"metric": Object {
|
||||
"accessor": 0,
|
||||
"aggType": "count",
|
||||
|
@ -72,6 +73,7 @@ Object {
|
|||
},
|
||||
"splitColumn": undefined,
|
||||
"splitRow": undefined,
|
||||
"truncateLegend": true,
|
||||
},
|
||||
"visData": Object {
|
||||
"columns": Array [
|
||||
|
|
|
@ -73,6 +73,20 @@ describe('PalettePicker', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('renders the long legend options for the elastic charts implementation', async () => {
|
||||
component = mountWithIntl(<PieOptions {...props} />);
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'pieLongLegendsOptions').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('not renders the long legend options for the vislib implementation', async () => {
|
||||
component = mountWithIntl(<PieOptions {...props} showElasticChartsOptions={false} />);
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'pieLongLegendsOptions').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the label position dropdown for the elastic charts implementation', async () => {
|
||||
component = mountWithIntl(<PieOptions {...props} />);
|
||||
await act(async () => {
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
SwitchOption,
|
||||
SelectOption,
|
||||
PalettePicker,
|
||||
LongLegendOptions,
|
||||
} from '../../../../vis_default_editor/public';
|
||||
import { VisEditorOptionsProps } from '../../../../visualizations/public';
|
||||
import { TruncateLabelsOption } from './truncate_labels';
|
||||
|
@ -169,6 +170,12 @@ const PieOptions = (props: PieOptionsProps) => {
|
|||
}}
|
||||
data-test-subj="visTypePieNestedLegendSwitch"
|
||||
/>
|
||||
<LongLegendOptions
|
||||
data-test-subj="pieLongLegendsOptions"
|
||||
truncateLegend={stateParams.truncateLegend ?? true}
|
||||
maxLegendLines={stateParams.maxLegendLines ?? 1}
|
||||
setValue={setValue}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{props.showElasticChartsOptions && palettesRegistry && (
|
||||
|
@ -276,7 +283,13 @@ const PieOptions = (props: PieOptionsProps) => {
|
|||
/>
|
||||
</>
|
||||
)}
|
||||
<TruncateLabelsOption value={stateParams.labels.truncate} setValue={setLabels} />
|
||||
<TruncateLabelsOption
|
||||
value={stateParams.labels.truncate}
|
||||
setValue={setLabels}
|
||||
disabled={
|
||||
props.showElasticChartsOptions && stateParams.labels.position === LabelPositions.INSIDE
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiFormRow, EuiFieldNumber } from '@elastic/eui';
|
||||
import { EuiFormRow, EuiFieldNumber, EuiIconTip } from '@elastic/eui';
|
||||
|
||||
export interface TruncateLabelsOptionProps {
|
||||
disabled?: boolean;
|
||||
|
@ -27,6 +27,16 @@ function TruncateLabelsOption({ disabled, value = null, setValue }: TruncateLabe
|
|||
})}
|
||||
fullWidth
|
||||
display="rowCompressed"
|
||||
labelAppend={
|
||||
<EuiIconTip
|
||||
content={i18n.translate('visTypePie.controls.truncateTooltip', {
|
||||
defaultMessage: 'Number of characters for labels positioned outside the chart.',
|
||||
})}
|
||||
position="top"
|
||||
type="iInCircle"
|
||||
color="subdued"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
data-test-subj="pieLabelTruncateInput"
|
||||
|
|
|
@ -279,6 +279,8 @@ export const createMockPieParams = (): PieVisParams => {
|
|||
},
|
||||
legendPosition: 'right',
|
||||
nestedLegend: false,
|
||||
maxLegendLines: 1,
|
||||
truncateLegend: true,
|
||||
distinctColors: false,
|
||||
palette: {
|
||||
name: 'default',
|
||||
|
|
|
@ -320,7 +320,16 @@ const PieComponent = (props: PieComponentProps) => {
|
|||
services.actions,
|
||||
services.fieldFormats
|
||||
)}
|
||||
theme={chartTheme}
|
||||
theme={[
|
||||
chartTheme,
|
||||
{
|
||||
legend: {
|
||||
labelOptions: {
|
||||
maxLines: visParams.truncateLegend ? visParams.maxLegendLines ?? 1 : 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
]}
|
||||
baseTheme={chartBaseTheme}
|
||||
onRenderChange={onRenderChange}
|
||||
/>
|
||||
|
|
|
@ -23,6 +23,8 @@ describe('interpreter/functions#pie', () => {
|
|||
legendPosition: 'right',
|
||||
isDonut: true,
|
||||
nestedLegend: true,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: true,
|
||||
distinctColors: false,
|
||||
palette: 'kibana_palette',
|
||||
labels: {
|
||||
|
|
|
@ -89,6 +89,19 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({
|
|||
}),
|
||||
default: false,
|
||||
},
|
||||
truncateLegend: {
|
||||
types: ['boolean'],
|
||||
help: i18n.translate('visTypePie.function.args.truncateLegendHelpText', {
|
||||
defaultMessage: 'Defines if the legend items will be truncated or not',
|
||||
}),
|
||||
default: true,
|
||||
},
|
||||
maxLegendLines: {
|
||||
types: ['number'],
|
||||
help: i18n.translate('visTypePie.function.args.maxLegendLinesHelpText', {
|
||||
defaultMessage: 'Defines the number of lines per legend item',
|
||||
}),
|
||||
},
|
||||
distinctColors: {
|
||||
types: ['boolean'],
|
||||
help: i18n.translate('visTypePie.function.args.distinctColorsHelpText', {
|
||||
|
|
|
@ -28,6 +28,8 @@ export const samplePieVis = {
|
|||
legendPosition: 'right',
|
||||
isDonut: true,
|
||||
nestedLegend: true,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
distinctColors: false,
|
||||
palette: 'kibana_palette',
|
||||
labels: {
|
||||
|
|
|
@ -50,6 +50,8 @@ export const toExpressionAst: VisToExpressionAst<PieVisParams> = async (vis, par
|
|||
addLegend: vis.params.addLegend,
|
||||
legendPosition: vis.params.legendPosition,
|
||||
nestedLegend: vis.params?.nestedLegend,
|
||||
truncateLegend: vis.params.truncateLegend,
|
||||
maxLegendLines: vis.params.maxLegendLines,
|
||||
distinctColors: vis.params?.distinctColors,
|
||||
isDonut: vis.params.isDonut,
|
||||
palette: vis.params?.palette?.name,
|
||||
|
|
|
@ -33,6 +33,8 @@ interface PieCommonParams {
|
|||
addLegend: boolean;
|
||||
legendPosition: Position;
|
||||
nestedLegend: boolean;
|
||||
truncateLegend: boolean;
|
||||
maxLegendLines: number;
|
||||
distinctColors: boolean;
|
||||
isDonut: boolean;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,8 @@ describe('getColumns', () => {
|
|||
},
|
||||
legendPosition: 'right',
|
||||
nestedLegend: false,
|
||||
maxLegendLines: 1,
|
||||
truncateLegend: false,
|
||||
palette: {
|
||||
name: 'default',
|
||||
type: 'palette',
|
||||
|
|
|
@ -63,6 +63,7 @@ export const getConfig = (
|
|||
config.linkLabel = {
|
||||
maxCount: Number.POSITIVE_INFINITY,
|
||||
maximumSection: Number.POSITIVE_INFINITY,
|
||||
maxTextLength: visParams.labels.truncate ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -151,12 +151,7 @@ export const getLayers = (
|
|||
showAccessor: (d: Datum) => d !== EMPTY_SLICE,
|
||||
nodeLabel: (d: unknown) => {
|
||||
if (col.format) {
|
||||
const formattedLabel = formatter.deserialize(col.format).convert(d) ?? '';
|
||||
if (visParams.labels.truncate && formattedLabel.length <= visParams.labels.truncate) {
|
||||
return formattedLabel;
|
||||
} else {
|
||||
return `${formattedLabel.slice(0, Number(visParams.labels.truncate))}\u2026`;
|
||||
}
|
||||
return formatter.deserialize(col.format).convert(d) ?? '';
|
||||
}
|
||||
return String(d);
|
||||
},
|
||||
|
|
|
@ -35,6 +35,8 @@ export const getPieVisTypeDefinition = ({
|
|||
addLegend: !showElasticChartsOptions,
|
||||
legendPosition: Position.Right,
|
||||
nestedLegend: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
distinctColors: false,
|
||||
isDonut: true,
|
||||
palette: {
|
||||
|
|
|
@ -8,7 +8,7 @@ Object {
|
|||
"area",
|
||||
],
|
||||
"visConfig": Array [
|
||||
"{\\"type\\":\\"area\\",\\"grid\\":{\\"categoryLines\\":false,\\"style\\":{\\"color\\":\\"#eee\\"}},\\"categoryAxes\\":[{\\"id\\":\\"CategoryAxis-1\\",\\"type\\":\\"category\\",\\"position\\":\\"bottom\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\"},\\"labels\\":{\\"show\\":true,\\"truncate\\":100},\\"title\\":{}}],\\"valueAxes\\":[{\\"id\\":\\"ValueAxis-1\\",\\"name\\":\\"LeftAxis-1\\",\\"type\\":\\"value\\",\\"position\\":\\"left\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\",\\"mode\\":\\"normal\\"},\\"labels\\":{\\"show\\":true,\\"rotate\\":0,\\"filter\\":false,\\"truncate\\":100},\\"title\\":{\\"text\\":\\"Sum of total_quantity\\"}}],\\"seriesParams\\":[{\\"show\\":\\"true\\",\\"type\\":\\"area\\",\\"mode\\":\\"stacked\\",\\"data\\":{\\"label\\":\\"Sum of total_quantity\\",\\"id\\":\\"1\\"},\\"drawLinesBetweenPoints\\":true,\\"showCircles\\":true,\\"circlesRadius\\":5,\\"interpolate\\":\\"linear\\",\\"valueAxis\\":\\"ValueAxis-1\\"}],\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"top\\",\\"times\\":[],\\"addTimeMarker\\":false,\\"thresholdLine\\":{\\"show\\":false,\\"value\\":10,\\"width\\":1,\\"style\\":\\"full\\",\\"color\\":\\"#E7664C\\"},\\"palette\\":{\\"name\\":\\"default\\"},\\"labels\\":{},\\"dimensions\\":{\\"x\\":{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"date\\",\\"params\\":{\\"pattern\\":\\"HH:mm:ss.SSS\\"}},\\"params\\":{}},\\"y\\":[{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\",\\"params\\":{\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}],\\"series\\":[{\\"accessor\\":2,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}",
|
||||
"{\\"type\\":\\"area\\",\\"grid\\":{\\"categoryLines\\":false,\\"style\\":{\\"color\\":\\"#eee\\"}},\\"categoryAxes\\":[{\\"id\\":\\"CategoryAxis-1\\",\\"type\\":\\"category\\",\\"position\\":\\"bottom\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\"},\\"labels\\":{\\"show\\":true,\\"truncate\\":100},\\"title\\":{}}],\\"valueAxes\\":[{\\"id\\":\\"ValueAxis-1\\",\\"name\\":\\"LeftAxis-1\\",\\"type\\":\\"value\\",\\"position\\":\\"left\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\",\\"mode\\":\\"normal\\"},\\"labels\\":{\\"show\\":true,\\"rotate\\":0,\\"filter\\":false,\\"truncate\\":100},\\"title\\":{\\"text\\":\\"Sum of total_quantity\\"}}],\\"seriesParams\\":[{\\"show\\":\\"true\\",\\"type\\":\\"area\\",\\"mode\\":\\"stacked\\",\\"data\\":{\\"label\\":\\"Sum of total_quantity\\",\\"id\\":\\"1\\"},\\"drawLinesBetweenPoints\\":true,\\"showCircles\\":true,\\"circlesRadius\\":5,\\"interpolate\\":\\"linear\\",\\"valueAxis\\":\\"ValueAxis-1\\"}],\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"top\\",\\"times\\":[],\\"addTimeMarker\\":false,\\"truncateLegend\\":true,\\"maxLegendLines\\":1,\\"thresholdLine\\":{\\"show\\":false,\\"value\\":10,\\"width\\":1,\\"style\\":\\"full\\",\\"color\\":\\"#E7664C\\"},\\"palette\\":{\\"name\\":\\"default\\"},\\"labels\\":{},\\"dimensions\\":{\\"x\\":{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"date\\",\\"params\\":{\\"pattern\\":\\"HH:mm:ss.SSS\\"}},\\"params\\":{}},\\"y\\":[{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\",\\"params\\":{\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}],\\"series\\":[{\\"accessor\\":2,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}",
|
||||
],
|
||||
},
|
||||
"getArgument": [Function],
|
||||
|
|
|
@ -32,6 +32,9 @@ Object {
|
|||
"legendPosition": Array [
|
||||
"top",
|
||||
],
|
||||
"maxLegendLines": Array [
|
||||
1,
|
||||
],
|
||||
"palette": Array [
|
||||
"default",
|
||||
],
|
||||
|
@ -51,6 +54,9 @@ Object {
|
|||
},
|
||||
],
|
||||
"times": Array [],
|
||||
"truncateLegend": Array [
|
||||
true,
|
||||
],
|
||||
"type": Array [
|
||||
"area",
|
||||
],
|
||||
|
|
|
@ -60,6 +60,8 @@ type XYSettingsProps = Pick<
|
|||
legendAction?: LegendAction;
|
||||
legendColorPicker: LegendColorPicker;
|
||||
legendPosition: Position;
|
||||
truncateLegend: boolean;
|
||||
maxLegendLines: number;
|
||||
};
|
||||
|
||||
function getValueLabelsStyling() {
|
||||
|
@ -93,6 +95,8 @@ export const XYSettings: FC<XYSettingsProps> = ({
|
|||
legendAction,
|
||||
legendColorPicker,
|
||||
legendPosition,
|
||||
maxLegendLines,
|
||||
truncateLegend,
|
||||
}) => {
|
||||
const themeService = getThemeService();
|
||||
const theme = themeService.useChartsTheme();
|
||||
|
@ -113,6 +117,9 @@ export const XYSettings: FC<XYSettingsProps> = ({
|
|||
crosshair: {
|
||||
...theme.crosshair,
|
||||
},
|
||||
legend: {
|
||||
labelOptions: { maxLines: truncateLegend ? maxLegendLines ?? 1 : 0 },
|
||||
},
|
||||
axes: {
|
||||
axisTitle: {
|
||||
padding: {
|
||||
|
|
|
@ -426,6 +426,8 @@ export const getVis = (bucketType: string) => {
|
|||
fittingFunction: 'linear',
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
maxLegendLines: 1,
|
||||
truncateLegend: true,
|
||||
radiusRatio: 9,
|
||||
thresholdLine: {
|
||||
show: false,
|
||||
|
@ -849,6 +851,8 @@ export const getStateParams = (type: string, thresholdPanelOn: boolean) => {
|
|||
legendPosition: 'right',
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
maxLegendLines: 1,
|
||||
truncateLegend: true,
|
||||
detailedTooltip: true,
|
||||
palette: {
|
||||
type: 'palette',
|
||||
|
|
|
@ -105,6 +105,26 @@ describe('PointSeries Editor', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('not renders the long legend options if showElasticChartsOptions is false', async () => {
|
||||
component = mountWithIntl(<PointSeriesOptions {...props} />);
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'xyLongLegendsOptions').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the long legend options if showElasticChartsOptions is true', async () => {
|
||||
const newVisProps = ({
|
||||
...props,
|
||||
extraProps: {
|
||||
showElasticChartsOptions: true,
|
||||
},
|
||||
} as unknown) as PointSeriesOptionsProps;
|
||||
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'xyLongLegendsOptions').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('not renders the fitting function for a bar chart', async () => {
|
||||
const newVisProps = ({
|
||||
...props,
|
||||
|
|
|
@ -11,7 +11,11 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { BasicOptions, SwitchOption } from '../../../../../../vis_default_editor/public';
|
||||
import {
|
||||
BasicOptions,
|
||||
SwitchOption,
|
||||
LongLegendOptions,
|
||||
} from '../../../../../../vis_default_editor/public';
|
||||
import { BUCKET_TYPES } from '../../../../../../data/public';
|
||||
|
||||
import { VisParams } from '../../../../types';
|
||||
|
@ -58,6 +62,14 @@ export function PointSeriesOptions(
|
|||
<EuiSpacer size="m" />
|
||||
|
||||
<BasicOptions {...props} legendPositions={legendPositions} />
|
||||
{props.extraProps?.showElasticChartsOptions && (
|
||||
<LongLegendOptions
|
||||
data-test-subj="xyLongLegendsOptions"
|
||||
truncateLegend={stateParams.truncateLegend ?? true}
|
||||
maxLegendLines={stateParams.maxLegendLines ?? 1}
|
||||
setValue={setValue}
|
||||
/>
|
||||
)}
|
||||
|
||||
{vis.data.aggs!.aggs.some(
|
||||
(agg) => agg.schema === 'segment' && agg.type.name === BUCKET_TYPES.DATE_HISTOGRAM
|
||||
|
|
|
@ -55,6 +55,18 @@ export const visTypeXyVisFn = (): VisTypeXyExpressionFunctionDefinition => ({
|
|||
defaultMessage: 'Show time marker',
|
||||
}),
|
||||
},
|
||||
truncateLegend: {
|
||||
types: ['boolean'],
|
||||
help: i18n.translate('visTypeXy.function.args.truncateLegend.help', {
|
||||
defaultMessage: 'Defines if the legend will be truncated or not',
|
||||
}),
|
||||
},
|
||||
maxLegendLines: {
|
||||
types: ['number'],
|
||||
help: i18n.translate('visTypeXy.function.args.args.maxLegendLines.help', {
|
||||
defaultMessage: 'Defines the maximum lines per legend item',
|
||||
}),
|
||||
},
|
||||
addLegend: {
|
||||
types: ['boolean'],
|
||||
help: i18n.translate('visTypeXy.function.args.addLegend.help', {
|
||||
|
@ -225,6 +237,8 @@ export const visTypeXyVisFn = (): VisTypeXyExpressionFunctionDefinition => ({
|
|||
addTooltip: args.addTooltip,
|
||||
legendPosition: args.legendPosition,
|
||||
addTimeMarker: args.addTimeMarker,
|
||||
maxLegendLines: args.maxLegendLines,
|
||||
truncateLegend: args.truncateLegend,
|
||||
categoryAxes: args.categoryAxes.map((categoryAxis) => ({
|
||||
...categoryAxis,
|
||||
type: categoryAxis.axisType,
|
||||
|
|
|
@ -88,6 +88,8 @@ export const sampleAreaVis = {
|
|||
legendPosition: 'right',
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
thresholdLine: {
|
||||
show: false,
|
||||
value: 10,
|
||||
|
@ -255,6 +257,8 @@ export const sampleAreaVis = {
|
|||
legendPosition: 'top',
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
thresholdLine: {
|
||||
show: false,
|
||||
value: 10,
|
||||
|
|
|
@ -194,6 +194,8 @@ export const toExpressionAst: VisToExpressionAst<VisParams> = async (vis, params
|
|||
type: vis.type.name as XyVisType,
|
||||
chartType: vis.params.type,
|
||||
addTimeMarker: vis.params.addTimeMarker,
|
||||
truncateLegend: vis.params.truncateLegend,
|
||||
maxLegendLines: vis.params.maxLegendLines,
|
||||
addLegend: vis.params.addLegend,
|
||||
addTooltip: vis.params.addTooltip,
|
||||
legendPosition: vis.params.legendPosition,
|
||||
|
|
|
@ -121,6 +121,8 @@ export interface VisParams {
|
|||
addTooltip: boolean;
|
||||
legendPosition: Position;
|
||||
addTimeMarker: boolean;
|
||||
truncateLegend: boolean;
|
||||
maxLegendLines: number;
|
||||
categoryAxes: CategoryAxis[];
|
||||
orderBucketsBySum?: boolean;
|
||||
labels: Labels;
|
||||
|
@ -158,6 +160,8 @@ export interface XYVisConfig {
|
|||
addTooltip: boolean;
|
||||
legendPosition: Position;
|
||||
addTimeMarker: boolean;
|
||||
truncateLegend: boolean;
|
||||
maxLegendLines: number;
|
||||
orderBucketsBySum?: boolean;
|
||||
labels: ExpressionValueLabel;
|
||||
thresholdLine: ExpressionValueThresholdLine;
|
||||
|
|
|
@ -345,6 +345,8 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
/>
|
||||
<XYSettings
|
||||
{...config}
|
||||
truncateLegend={visParams.truncateLegend}
|
||||
maxLegendLines={visParams.maxLegendLines}
|
||||
showLegend={showLegend}
|
||||
onPointerUpdate={handleCursorUpdate}
|
||||
legendPosition={legendPosition}
|
||||
|
|
|
@ -114,6 +114,8 @@ export const getAreaVisTypeDefinition = (
|
|||
fittingFunction: Fit.Linear,
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
radiusRatio: 9,
|
||||
thresholdLine: {
|
||||
show: false,
|
||||
|
|
|
@ -116,6 +116,8 @@ export const getHistogramVisTypeDefinition = (
|
|||
legendPosition: Position.Right,
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
labels: {
|
||||
show: false,
|
||||
},
|
||||
|
|
|
@ -116,6 +116,8 @@ export const getHorizontalBarVisTypeDefinition = (
|
|||
legendPosition: Position.Right,
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
labels: {},
|
||||
radiusRatio: 0,
|
||||
thresholdLine: {
|
||||
|
|
|
@ -114,6 +114,8 @@ export const getLineVisTypeDefinition = (
|
|||
fittingFunction: Fit.Linear,
|
||||
times: [],
|
||||
addTimeMarker: false,
|
||||
truncateLegend: true,
|
||||
maxLegendLines: 1,
|
||||
labels: {},
|
||||
radiusRatio: 9,
|
||||
thresholdLine: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue