[Canvas] PieVis integration to Canvas. (#124325)

* Added the sidebar of the pieVis.

* Added the element of the pieVis.

* Removed pieVis from exposed elements.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Yaroslav Kuznietsov 2022-08-15 15:03:55 +03:00 committed by GitHub
parent 1f5b803d6f
commit 99ea41c237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 947 additions and 7 deletions

View file

@ -177,6 +177,6 @@ Object {
}
`;
exports[`interpreter/functions#mosaicVis throws error if provided more than 2 buckets 1`] = `"More than 2 buckets are not supported"`;
exports[`interpreter/functions#mosaicVis throws error if provided more than 2 buckets 1`] = `"More than 2 buckets are not supported."`;
exports[`interpreter/functions#mosaicVis throws error if provided split row and split column at once 1`] = `"A split row and column are specified. Expression is supporting only one of them at once."`;

View file

@ -177,6 +177,6 @@ Object {
}
`;
exports[`interpreter/functions#treemapVis throws error if provided more than 2 buckets 1`] = `"More than 2 buckets are not supported"`;
exports[`interpreter/functions#treemapVis throws error if provided more than 2 buckets 1`] = `"More than 2 buckets are not supported."`;
exports[`interpreter/functions#treemapVis throws error if provided split row and split column at once 1`] = `"A split row and column are specified. Expression is supporting only one of them at once."`;

View file

@ -123,9 +123,10 @@ export const strings = {
export const errors = {
moreThanNBucketsAreNotSupportedError: (maxLength: number) =>
i18n.translate('expressionPartitionVis.reusable.function.errors.moreThenNumberBuckets', {
defaultMessage: 'More than {maxLength} buckets are not supported',
defaultMessage: 'More than {maxLength} buckets are not supported.',
values: { maxLength },
}),
splitRowAndSplitColumnAreSpecifiedError: () =>
i18n.translate('expressionPartitionVis.reusable.function.errors.splitRowAndColumnSpecified', {
defaultMessage:

View file

@ -12,7 +12,8 @@ export const heatmap: ElementFactory = () => ({
type: 'chart',
help: 'Heatmap visualization',
icon: 'heatmap',
expression: `filters
expression: `kibana
| selectFilter
| demodata
| head 10
| heatmap xAccessor={visdimension "age"} yAccessor={visdimension "project"} valueAccessor={visdimension "cost"}

View file

@ -38,6 +38,7 @@ import { heatmap } from './heatmap';
import { SetupInitializer } from '../plugin';
import { ElementFactory } from '../../types';
import { pieVis } from './pie_vis';
const elementSpecs = [
areaChart,
@ -68,6 +69,8 @@ const elementSpecs = [
heatmap,
];
const notExposedElementsSpecs = [metricVis, legacyMetricVis, pieVis];
const initializeElementFactories = [metricElementInitializer];
export const initializeElements: SetupInitializer<ElementFactory[]> = (core, plugins) => {
@ -78,8 +81,8 @@ export const initializeElements: SetupInitializer<ElementFactory[]> = (core, plu
return applyElementStrings(specs);
};
// For testing purpose. Will be removed after exposing `metricVis` element.
// For testing purpose. Will be removed after exposing `metricVis`, pieVis elements.
export const initializeElementsSpec: SetupInitializer<ElementFactory[]> = (core, plugins) => {
const specs = initializeElements(core, plugins);
return [...applyElementStrings([metricVis, legacyMetricVis]), ...specs];
return [...applyElementStrings(notExposedElementsSpecs), ...specs];
};

View file

@ -0,0 +1,21 @@
/*
* 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 { ElementFactory } from '../../../types';
export const pieVis: ElementFactory = () => ({
name: 'pieVis',
displayName: '(New) Pie Vis',
type: 'chart',
help: 'Pie visualization',
icon: 'visPie',
expression: `kibana
| selectFilter
| demodata
| head 10
| pieVis metric={visdimension "age"} buckets={visdimension "project"} buckets={visdimension "cost"} legendDisplay="default"
| render`,
});

View file

@ -34,6 +34,7 @@ import { toggle } from './toggle';
import { visdimension } from './vis_dimension';
import { colorPicker } from './color_picker';
import { editor } from './editor';
import { partitionLabels } from './partition_labels';
import { SetupInitializer } from '../../plugin';
@ -55,6 +56,7 @@ export const args = [
visdimension,
colorPicker,
editor,
partitionLabels,
];
export const initializers = [dateFormatInitializer, numberFormatInitializer];

View file

@ -0,0 +1,25 @@
/*
* 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 { ExpressionAstExpression } from '@kbn/expressions-plugin/common';
export const defaultExpression = (): ExpressionAstExpression => ({
type: 'expression',
chain: [
{
type: 'function',
function: 'partitionLabels',
arguments: {
show: [true],
position: ['default'],
values: [true],
percentDecimals: [2],
valuesFormat: ['percent'],
},
},
],
});

View file

@ -0,0 +1,154 @@
/*
* 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 React, { ChangeEvent, MouseEvent, FunctionComponent, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import {
EuiFormRow,
EuiRange,
EuiSelect,
EuiSelectOption,
EuiSpacer,
EuiSwitch,
EuiSwitchEvent,
EuiText,
} from '@elastic/eui';
import { ExpressionAstExpression } from '@kbn/expressions-plugin/common';
import { set } from 'lodash';
import { defaultExpression } from './default_expression';
import { Fields } from './types';
import { getFieldPath, getFieldValue } from './utils';
import { ArgumentStrings } from '../../../../i18n';
const { PartitionLabels: strings } = ArgumentStrings;
export interface Props {
onValueChange: (argValue: ExpressionAstExpression) => void;
argValue: null | ExpressionAstExpression;
}
const SHOW_FIELD = 'show';
const POSITION_FIELD = 'position';
const VALUES_FIELD = 'values';
const VALUES_FORMAT_FIELD = 'valuesFormat';
const PERCENT_DECIMALS_FIELD = 'percentDecimals';
export const ExtendedTemplate: FunctionComponent<Props> = ({ onValueChange, argValue }) => {
const showLabels = getFieldValue(argValue, SHOW_FIELD);
const showValues = getFieldValue(argValue, VALUES_FIELD);
const valueFormat = getFieldValue(argValue, VALUES_FORMAT_FIELD);
const percentDecimals = getFieldValue(argValue, PERCENT_DECIMALS_FIELD);
const positions: EuiSelectOption[] = [
{ text: strings.getPositionDefaultLabel(), value: 'default' },
{ text: strings.getPositionInsideLabel(), value: 'inside' },
];
const valuesFormats: EuiSelectOption[] = [
{ text: strings.getValuesFormatValueLabel(), value: 'value' },
{ text: strings.getValuesFormatPercentLabel(), value: 'percent' },
];
useEffect(() => {
if (!argValue) {
onValueChange(defaultExpression());
}
}, [argValue, onValueChange]);
const onChangeField = useCallback(
(field: Fields, value: unknown) => {
const path = getFieldPath(field);
const oldArgValue = argValue ?? defaultExpression();
const newArgValue = set(oldArgValue, path, value);
onValueChange(newArgValue);
},
[argValue, onValueChange]
);
const onToggleFieldChange = useCallback(
(field: Fields) => (event: EuiSwitchEvent) => {
onChangeField(field, event.target.checked);
},
[onChangeField]
);
const onCommonFieldChange = useCallback(
(field: Fields) =>
(
event: ChangeEvent<HTMLInputElement | HTMLSelectElement> | MouseEvent<HTMLButtonElement>
) => {
onChangeField(field, event.currentTarget.value);
},
[onChangeField]
);
if (!showLabels) {
return (
<EuiText color="subdued" size="xs">
<p>{strings.getSwitchedOffShowLabelsLabel()}</p>
</EuiText>
);
}
return (
<>
<EuiFormRow label={strings.getPositionLabel()} display="columnCompressed">
<EuiSelect
compressed
value={getFieldValue(argValue, POSITION_FIELD)}
options={positions}
onChange={onCommonFieldChange(POSITION_FIELD)}
/>
</EuiFormRow>
<EuiSpacer size="s" />
<EuiFormRow label={strings.getValuesLabel()} display="columnCompressedSwitch">
<EuiSwitch
compressed
checked={showValues}
onChange={onToggleFieldChange(VALUES_FIELD)}
label={strings.getValuesToggle()}
/>
</EuiFormRow>
{showValues && (
<EuiFormRow label={strings.getValuesFormatLabel()} display="columnCompressed">
<EuiSelect
compressed
value={valueFormat}
options={valuesFormats}
onChange={onCommonFieldChange(VALUES_FORMAT_FIELD)}
/>
</EuiFormRow>
)}
{showValues && valueFormat === 'percent' && (
<EuiFormRow label={strings.getPercentDecimalsLabel()} display="columnCompressed">
<EuiRange
compressed
min={0}
max={10}
step={1}
showLabels
showInput
value={percentDecimals}
onChange={(e, isValid) => {
if (isValid) {
onCommonFieldChange(PERCENT_DECIMALS_FIELD)(e);
}
}}
/>
</EuiFormRow>
)}
</>
);
};
ExtendedTemplate.propTypes = {
onValueChange: PropTypes.func.isRequired,
argValue: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).isRequired,
};
ExtendedTemplate.displayName = 'PartitionLabelsExtendedArg';

View file

@ -0,0 +1,21 @@
/*
* 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 { templateFromReactComponent } from '../../../../public/lib/template_from_react_component';
import { ExtendedTemplate } from './extended_template';
import { SimpleTemplate } from './simple_template';
import { ArgumentStrings } from '../../../../i18n';
const { PartitionLabels: strings } = ArgumentStrings;
export const partitionLabels = () => ({
name: 'partitionLabels',
displayName: strings.getDisplayName(),
help: strings.getHelp(),
simpleTemplate: templateFromReactComponent(SimpleTemplate),
template: templateFromReactComponent(ExtendedTemplate),
});

View file

@ -0,0 +1,54 @@
/*
* 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 React, { FunctionComponent, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
import { ExpressionAstExpression } from '@kbn/expressions-plugin/common';
import { set } from 'lodash';
import { defaultExpression } from './default_expression';
import { getFieldPath, getFieldValue } from './utils';
export interface Props {
onValueChange: (argValue: ExpressionAstExpression) => void;
argValue: null | ExpressionAstExpression;
}
const SHOW_FIELD = 'show';
export const SimpleTemplate: FunctionComponent<Props> = ({ onValueChange, argValue }) => {
const showValuePath = getFieldPath(SHOW_FIELD);
useEffect(() => {
if (!argValue) {
onValueChange(defaultExpression());
}
}, [argValue, onValueChange]);
const onToggle = useCallback(
(event: EuiSwitchEvent) => {
const oldArgValue = argValue ?? defaultExpression();
const newArgValue = set(oldArgValue, showValuePath, event.target.checked);
onValueChange(newArgValue);
},
[argValue, onValueChange, showValuePath]
);
const showLabels = getFieldValue(argValue, SHOW_FIELD, false);
return (
<EuiSwitch compressed checked={showLabels} onChange={onToggle} showLabel={false} label="" />
);
};
SimpleTemplate.propTypes = {
onValueChange: PropTypes.func.isRequired,
argValue: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).isRequired,
};
SimpleTemplate.displayName = 'PartitionLabelsSimpleArg';

View file

@ -0,0 +1,16 @@
/*
* 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.
*/
export interface PartitionLabelsArguments {
show: boolean;
position: 'inside' | 'default';
values: boolean;
valuesFormat: 'percent' | 'value';
percentDecimals: number;
}
export type Fields = keyof PartitionLabelsArguments;

View file

@ -0,0 +1,25 @@
/*
* 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 { ExpressionAstExpression } from '@kbn/expressions-plugin/common';
import { get } from 'lodash';
import { PartitionLabelsArguments } from './types';
export const getFieldPath = (field: keyof PartitionLabelsArguments) =>
`chain.0.arguments.${field}.0`;
export const getFieldValue = (
ast: null | ExpressionAstExpression,
field: keyof PartitionLabelsArguments,
defaultValue?: unknown
) => {
if (!ast) {
return null;
}
return get(ast, getFieldPath(field), defaultValue);
};

View file

@ -11,5 +11,14 @@ import { tagcloud } from './tagcloud';
import { metricVis } from './metric_vis';
import { heatmapLegend } from './heatmap_legend';
import { heatmapGrid } from './heatmap_grid';
import { partitionLabels } from './partition_labels';
export const modelSpecs = [pointseries, math, tagcloud, metricVis, heatmapLegend, heatmapGrid];
export const modelSpecs = [
pointseries,
math,
tagcloud,
metricVis,
heatmapLegend,
heatmapGrid,
partitionLabels,
];

View file

@ -0,0 +1,77 @@
/*
* 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 { get } from 'lodash';
import { getState, getValue } from '../../../public/lib/resolved_arg';
import { ModelStrings } from '../../../i18n';
import { ResolvedColumns } from '../../../public/expression_types/arg';
const { PartitionLabels: strings } = ModelStrings;
export const partitionLabels = () => ({
name: 'partitionLabels',
displayName: strings.getDisplayName(),
args: [
{
name: 'show',
displayName: strings.getShowDisplayName(),
help: strings.getShowHelp(),
argType: 'toggle',
default: true,
},
{
name: 'position',
displayName: strings.getPositionDisplayName(),
help: strings.getPositionHelp(),
argType: 'select',
default: 'default',
options: {
choices: [
{ value: 'default', name: strings.getPositionDefaultOption() },
{ value: 'inside', name: strings.getPositionInsideOption() },
],
},
},
{
name: 'values',
displayName: strings.getValuesDisplayName(),
help: strings.getValuesHelp(),
argType: 'toggle',
default: true,
},
{
name: 'percentDecimals',
displayName: strings.getPercentDecimalsDisplayName(),
help: strings.getPercentDecimalsHelp(),
argType: 'range',
default: 2,
options: {
min: 0,
max: 10,
},
},
{
name: 'valuesFormat',
displayName: strings.getValuesFormatDisplayName(),
help: strings.getValuesFormatHelp(),
argType: 'select',
default: 'percent',
options: {
choices: [
{ value: 'percent', name: strings.getValuesFormatPercentOption() },
{ value: 'value', name: strings.getValuesFormatValueOption() },
],
},
},
],
resolve({ context }: any): ResolvedColumns {
if (getState(context) !== 'ready') {
return { columns: [] };
}
return { columns: get(getValue(context), 'columns', []) };
},
});

View file

@ -33,6 +33,7 @@ import { table } from './table';
// @ts-expect-error untyped local
import { timefilterControl } from './timefilterControl';
import { heatmap } from './heatmap';
import { pieVis } from './pie_vis';
import { SetupInitializer } from '../../plugin';
@ -51,6 +52,7 @@ export const viewSpecs = [
table,
timefilterControl,
heatmap,
pieVis,
];
export const viewInitializers = [metricInitializer];

View file

@ -0,0 +1,185 @@
/*
* 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 { get } from 'lodash';
import { ResolvedColumns } from '../../../public/expression_types/arg';
import { ViewStrings } from '../../../i18n';
import { getState, getValue } from '../../../public/lib/resolved_arg';
const { PieVis: pieVisStrings, PartitionVis: strings } = ViewStrings;
export const pieVis = () => ({
name: 'pieVis',
displayName: pieVisStrings.getDisplayName(),
args: [
{
name: 'metric',
displayName: strings.getMetricColumnDisplayName(),
help: strings.getMetricColumnHelp(),
argType: 'vis_dimension',
default: `{visdimension}`,
},
{
name: 'buckets',
displayName: strings.getBucketColumnDisplayName(),
help: strings.getBucketColumnHelp(),
argType: 'vis_dimension',
default: `{visdimension}`,
multi: true,
},
{
name: 'splitColumn',
displayName: strings.getSplitColumnDisplayName(),
help: strings.getSplitColumnHelp(),
argType: 'vis_dimension',
default: `{visdimension}`,
},
{
name: 'splitRow',
displayName: strings.getSplitRowDisplayName(),
help: strings.getSplitRowHelp(),
argType: 'vis_dimension',
default: `{visdimension}`,
},
{
name: 'isDonut',
displayName: strings.getIsDonutDisplayName(),
help: strings.getIsDonutHelp(),
argType: 'toggle',
default: false,
options: {
labelValue: strings.getIsDonutHelp(),
},
},
{
name: 'emptySizeRatio',
displayName: strings.getEmptySizeRatioDisplayName(),
help: strings.getEmptySizeRatioHelp(),
argType: 'range',
default: 0.4,
options: {
min: 0,
max: 1,
step: 0.01,
},
},
{
name: 'palette',
argType: 'palette',
help: strings.getPaletteHelp(),
},
{
name: 'distinctColors',
displayName: strings.getDistictColorsDisplayName(),
help: strings.getDistictColorsHelp(),
argType: 'toggle',
default: false,
options: {
labelValue: strings.getDistictColorsToggleLabel(),
},
},
{
name: 'addTooltip',
displayName: strings.getAddTooltipDisplayName(),
help: strings.getAddTooltipHelp(),
argType: 'toggle',
default: true,
options: {
labelValue: strings.getAddTooltipToggleLabel(),
},
},
{
name: 'legendDisplay',
displayName: strings.getLegendDisplayName(),
help: strings.getLegendDisplayHelp(),
argType: 'select',
default: 'default',
options: {
choices: [
{ value: 'default', name: strings.getLegendDisplayDefaultOption() },
{ value: 'show', name: strings.getLegendDisplayShowOption() },
{ value: 'hide', name: strings.getLegendDisplayHideOption() },
],
},
},
{
name: 'legendPosition',
displayName: strings.getLegendPositionDisplayName(),
help: strings.getLegendPositionHelp(),
argType: 'select',
default: 'right',
options: {
choices: [
{ value: 'top', name: strings.getLegendPositionTopOption() },
{ value: 'right', name: strings.getLegendPositionRightOption() },
{ value: 'bottom', name: strings.getLegendPositionBottomOption() },
{ value: 'left', name: strings.getLegendPositionLeftOption() },
],
},
},
{
name: 'nestedLegend',
displayName: strings.getNestedLegendDisplayName(),
help: strings.getNestedLegendHelp(),
argType: 'toggle',
default: false,
options: {
labelValue: strings.getNestedLegendToggleLabel(),
},
},
{
name: 'truncateLegend',
displayName: strings.getTruncateLegendDisplayName(),
help: strings.getTruncateLegendHelp(),
argType: 'toggle',
default: true,
options: {
labelValue: strings.getTruncateLegendToggleLabel(),
},
},
{
name: 'maxLegendLines',
displayName: strings.getMaxLegendLinesDisplayName(),
help: strings.getMaxLegendLinesHelp(),
argType: 'number',
default: 1,
},
{
name: 'respectSourceOrder',
displayName: strings.getRespectSourceOrderDisplayName(),
help: strings.getRespectSourceOrderHelp(),
argType: 'toggle',
default: true,
options: {
labelValue: strings.getRespectSourceOrderToggleLabel(),
},
},
{
name: 'startFromSecondLargestSlice',
displayName: strings.getStartFromSecondLargestSliceDisplayName(),
help: strings.getStartFromSecondLargestSliceHelp(),
argType: 'toggle',
default: true,
options: {
labelValue: strings.getStartFromSecondLargestSliceToggleLabel(),
},
},
{
name: 'labels',
displayName: strings.getLabelsDisplayName(),
help: strings.getLabelsHelp(),
argType: 'partitionLabels',
},
],
resolve({ context }: any): ResolvedColumns {
if (getState(context) !== 'ready') {
return { columns: [] };
}
return { columns: get(getValue(context), 'columns', []) };
},
});

View file

@ -254,4 +254,12 @@ export const getElementStrings = (): ElementStringDict => ({
defaultMessage: 'Heatmap visualization',
}),
},
pieVis: {
displayName: i18n.translate('xpack.canvas.elements.pieVisDisplayName', {
defaultMessage: '(New) Pie Vis',
}),
help: i18n.translate('xpack.canvas.elements.pieVisHelpText', {
defaultMessage: 'Pie visualization',
}),
},
});

View file

@ -244,6 +244,56 @@ export const ArgumentStrings = {
defaultMessage: 'Custom',
}),
},
PartitionLabels: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.arguments.partitionLabelsTitle', {
defaultMessage: 'Partition labels',
}),
getHelp: () =>
i18n.translate('xpack.canvas.uis.arguments.partitionLabelsLabel', {
defaultMessage: 'Labels configuration',
}),
getPositionDefaultLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.positionDefaultLabel', {
defaultMessage: 'Default',
}),
getPositionInsideLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.positionInsideLabel', {
defaultMessage: 'Inside',
}),
getPositionLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.positionLabel', {
defaultMessage: 'Position',
}),
getValuesLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.valuesLabel', {
defaultMessage: 'Values',
}),
getValuesToggle: () =>
i18n.translate('xpack.canvas.uis.arguments.valuesToggle', {
defaultMessage: 'Show values',
}),
getValuesFormatLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.valuesFormatLabel', {
defaultMessage: 'Values format',
}),
getValuesFormatValueLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.valuesFormatValueLabel', {
defaultMessage: 'Value',
}),
getValuesFormatPercentLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.valuesFormatPercentLabel', {
defaultMessage: 'Percent',
}),
getPercentDecimalsLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.percentDecimals', {
defaultMessage: 'Percent decimals',
}),
getSwitchedOffShowLabelsLabel: () =>
i18n.translate('xpack.canvas.uis.arguments.turnedOffShowLabelsLabel', {
defaultMessage: 'Switch on to view labels settings',
}),
},
Color: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.arguments.colorTitle', {
@ -727,6 +777,71 @@ export const ModelStrings = {
defaultMessage: 'Specifies whether or not the X-axis title is visible',
}),
},
PartitionLabels: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.parititionLabels.title', {
defaultMessage: 'Configure chart labels',
}),
getShowDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.showTitle', {
defaultMessage: 'Show labels',
}),
getShowHelp: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.showDisplayName', {
defaultMessage: 'Show labels in a chart',
}),
getPositionDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.positionDisplayName', {
defaultMessage: 'Defines the label position',
}),
getPositionHelp: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.positionTitle', {
defaultMessage: 'Defines the label position',
}),
getPositionDefaultOption: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.positionDefaultOption', {
defaultMessage: 'Default',
}),
getPositionInsideOption: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.positionInsideOption', {
defaultMessage: 'Inside',
}),
getValuesDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.valuesDisplayName', {
defaultMessage: 'Show values in labels',
}),
getValuesHelp: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.valuesHelp', {
defaultMessage: 'Show values in labels',
}),
getPercentDecimalsDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.percentDecimalsDisplayName', {
defaultMessage: 'Percent decimals in in labels',
}),
getPercentDecimalsHelp: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.percentDecimalsHelp', {
defaultMessage: 'Defines the number of decimals that will appear on the values as percent',
}),
getValuesFormatDisplayName: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.valuesFormatDisplayName', {
defaultMessage: 'Defines the format of the values',
}),
getValuesFormatHelp: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.valuesFormatHelp', {
defaultMessage: 'Defines the format of the values',
}),
getValuesFormatPercentOption: () =>
i18n.translate(
'xpack.canvas.uis.models.partitionLabels.args.valuesFormatPercentDisplayName',
{
defaultMessage: 'Percent',
}
),
getValuesFormatValueOption: () =>
i18n.translate('xpack.canvas.uis.models.partitionLabels.args.valuesFormatValueDisplayName', {
defaultMessage: 'Value',
}),
},
};
export const TransformStrings = {
@ -1572,4 +1687,218 @@ export const ViewStrings = {
defaultMessage: 'If is set to true, the last range value will be right open',
}),
},
PieVis: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.pieVisTitle', {
defaultMessage: '(New) Pie Visualization',
}),
},
PartitionVis: {
getMetricColumnDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.metricDisplayName', {
defaultMessage: 'Metric',
}),
getMetricColumnHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.metricHelp', {
defaultMessage: 'Metric dimension configuration',
}),
getBucketColumnDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.bucketDisplayName', {
defaultMessage: 'Bucket',
}),
getBucketColumnHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.bucketHelp', {
defaultMessage: 'Bucket dimension configuration',
}),
getSplitRowDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.splitRowDisplayName', {
defaultMessage: 'Split row',
}),
getSplitRowHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.splitRowHelp', {
defaultMessage: 'Split row dimension configuration',
}),
getSplitColumnDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.splitColumnDisplayName', {
defaultMessage: 'Split column',
}),
getSplitColumnHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.splitColumnHelp', {
defaultMessage: 'Split column dimension configuration',
}),
getAddTooltipDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.addTooltipDisplayName', {
defaultMessage: 'Tooltip',
}),
getAddTooltipHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.addTooltipHelp', {
defaultMessage: 'Show tooltip on hover',
}),
getAddTooltipToggleLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.addTooltipToggleLabel', {
defaultMessage: 'Show tooltip',
}),
getLegendPositionDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionTitle', {
defaultMessage: 'Placement',
}),
getLegendPositionHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionLabel', {
defaultMessage: 'Set the legend position on the right, top, left, or bottom',
}),
getLegendPositionTopOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionTopLabel', {
defaultMessage: 'Top',
}),
getLegendPositionBottomOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionBottomLabel', {
defaultMessage: 'Bottom',
}),
getLegendPositionLeftOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionLeftLabel', {
defaultMessage: 'Left',
}),
getLegendPositionRightOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendPositionRightLabel', {
defaultMessage: 'Right',
}),
getLegendDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendDisplayTitle', {
defaultMessage: 'Legend view',
}),
getLegendDisplayHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendDisplayLabel', {
defaultMessage: 'Show or hide the pie legend',
}),
getLegendDisplayDefaultOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendDisplayDefaultLabel', {
defaultMessage: 'Default',
}),
getLegendDisplayShowOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendDisplayShowLabel', {
defaultMessage: 'Show',
}),
getLegendDisplayHideOption: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.legendDisplayHideLabel', {
defaultMessage: 'Hide',
}),
getNestedLegendDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.nestedLegendDisplayName', {
defaultMessage: 'Detail legend',
}),
getNestedLegendHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.nestedLegendHelp', {
defaultMessage: 'Include details in the legend',
}),
getNestedLegendToggleLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.nestedLegendToggleLabel', {
defaultMessage: 'Show details',
}),
getTruncateLegendDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.truncateLegendDisplayName', {
defaultMessage: 'Legend text',
}),
getTruncateLegendHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.truncateLegendHelp', {
defaultMessage: 'Truncate the legend when it reaches the maximum width',
}),
getTruncateLegendToggleLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.truncateLegendToggleLabel', {
defaultMessage: 'Truncate when long',
}),
getMaxLegendLinesDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.maxLegendLinesDisplayName', {
defaultMessage: 'Max legend lines',
}),
getMaxLegendLinesHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.maxLegendLinesHelp', {
defaultMessage: 'Set the maximum number of lines for each legend item',
}),
getDistictColorsDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.distinctColorsDisplayName', {
defaultMessage: 'Slice colors',
}),
getDistictColorsHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.distinctColorsHelp', {
defaultMessage: 'Use different colors for slices with unequal values',
}),
getDistictColorsToggleLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.distictColorsToggleLabel', {
defaultMessage: 'Use distinct colors',
}),
getRespectSourceOrderDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.respectSourceOrderDisplayName', {
defaultMessage: 'Order of data',
}),
getRespectSourceOrderToggleLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.respectSourceOrderToggleLabel', {
defaultMessage: 'Use original order',
}),
getRespectSourceOrderHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.respectSourceOrderHelp', {
defaultMessage: 'Display the data in its original order instead of sorting it',
}),
getIsDonutDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.isDonutDisplayName', {
defaultMessage: 'Donut',
}),
getIsDonutHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.isDonutHelp', {
defaultMessage: 'Show donut chart',
}),
getEmptySizeRatioDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.emptySizeRatioDisplayName', {
defaultMessage: 'Donut hole size',
}),
getEmptySizeRatioHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.emptySizeRatioHelp', {
defaultMessage: 'Set the inner diameter of the donut hole',
}),
getPaletteHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.paletteHelp', {
defaultMessage: 'Specify the colors for the slices in the pie',
}),
getStartFromSecondLargestSliceDisplayName: () =>
i18n.translate(
'xpack.canvas.uis.views.partitionVis.args.startFromSecondLargestSliceDisplayName',
{
defaultMessage: 'Slice placement',
}
),
getStartFromSecondLargestSliceHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.startFromSecondLargestSliceHelp', {
defaultMessage: 'Place the second largest slice in the first position of the pie',
}),
getStartFromSecondLargestSliceToggleLabel: () =>
i18n.translate(
'xpack.canvas.uis.views.partitionVis.args.startFromSecondLargestSliceToggleLabel',
{
defaultMessage: 'Start with second slice',
}
),
getLabelsDisplayName: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.labelsDisplayName', {
defaultMessage: 'Label configuration',
}),
getLabelsHelp: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.args.labelsHelp', {
defaultMessage: 'Show label settings',
}),
getEnableLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.options.enableHelp', {
defaultMessage: 'Enable',
}),
getSaveLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.options.saveHelp', {
defaultMessage: 'Save',
}),
getTruncateLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.options.truncateHelp', {
defaultMessage: 'Truncate',
}),
getShowLabel: () =>
i18n.translate('xpack.canvas.uis.views.partitionVis.options.showHelp', {
defaultMessage: 'Show',
}),
},
};

View file

@ -3,5 +3,10 @@
}
.canvasArg__addPopover {
@include euiScrollBar;
width: 250px;
max-height: 500px;
overflow-y: auto;
}

View file

@ -95,6 +95,8 @@ export class Popover extends Component<Props, State> {
isOpen={this.state.isPopoverOpen}
closePopover={this.closePopover}
container={appWrapper}
hasArrow={false}
offset={10}
>
{children({ closePopover: this.closePopover })}
</EuiPopoverAny>