From 446eb18067ad40ea09c86f3ed006b995ea855faf Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 30 Jun 2020 14:09:24 +0200 Subject: [PATCH 01/19] axis colors --- .../metric_color_configuration.ts | 42 +++++ .../public/xy_visualization/to_expression.ts | 1 + .../lens/public/xy_visualization/types.ts | 5 + .../xy_visualization/xy_config_panel.tsx | 150 ++++++++++++------ .../public/xy_visualization/xy_expression.tsx | 9 ++ 5 files changed, 156 insertions(+), 51 deletions(-) create mode 100644 x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts diff --git a/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts b/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts new file mode 100644 index 00000000000000..5877b731fe4289 --- /dev/null +++ b/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { euiPaletteColorBlind } from '@elastic/eui'; +import { LayerConfig, YConfig } from './types'; +const ROTATION_LEN = 10; + +export const getColorConfig = (layers: LayerConfig[]) => { + const palette = euiPaletteColorBlind({ + rotations: layers.filter((l: LayerConfig) => l.splitAccessor).length + 1, + }); + + let counter = 0; + let rotationOffset = 0; + const colorConfig: Record = {}; + + for (let l = 0; l < layers.length; l++) { + const layer = layers[l]; + for (let a = 0; a < layer.accessors.length; a++) { + const accessor = layer.accessors[a]; + colorConfig[accessor] = + layer?.yConfig?.find((yConfig) => yConfig.forAccessor === accessor)?.color || + palette[(counter % ROTATION_LEN) + rotationOffset * ROTATION_LEN]; + counter += 1; + } + if (layer.splitAccessor) { + ++rotationOffset; + counter = 0; + } + } + return colorConfig; +}; + +export const getColorForPanel = (layer: LayerConfig, accessor: string, layers: LayerConfig[]) => { + return ( + layer?.yConfig?.find((yConfig: YConfig) => yConfig.forAccessor === accessor)?.color || + getColorConfig(layers)[accessor] + ); +}; diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 6ec22270d8b183..28f6871644d06b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -189,6 +189,7 @@ export const buildExpression = ( arguments: { forAccessor: [yConfig.forAccessor], axisMode: [yConfig.axisMode], + color: [yConfig.color], }, }, ], diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index e62c5f60a58e16..8ea9683ca042cb 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -100,6 +100,10 @@ export const yAxisConfig: ExpressionFunctionDefinition< options: ['auto', 'left', 'right'], help: 'The axis mode of the metric', }, + color: { + types: ['string'], + help: 'The color of the series', + }, }, fn: function fn(input: unknown, args: YConfig) { return { @@ -195,6 +199,7 @@ export type YAxisMode = 'auto' | 'left' | 'right'; export interface YConfig { forAccessor: string; axisMode?: YAxisMode; + color?: string; } export interface LayerConfig { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 3e73cd256bdbf1..0a46f9a575a983 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -6,11 +6,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonGroup, EuiFormRow, htmlIdGenerator } from '@elastic/eui'; +import { + EuiButtonGroup, + EuiFormRow, + htmlIdGenerator, + EuiForm, + EuiColorPicker, + EuiCallOut, +} from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; import { isHorizontalChart, isHorizontalSeries } from './state_helpers'; import { trackUiEvent } from '../lens_ui_telemetry'; +import { getColorForPanel } from './metric_color_configuration'; type UnwrapArray = T extends Array ? P : T; @@ -82,58 +90,98 @@ export function DimensionEditor({ (layer.yConfig && layer.yConfig?.find((yAxisConfig) => yAxisConfig.forAccessor === accessor)?.axisMode) || 'auto'; + + const color = getColorForPanel(layer, accessor, state.layers); return ( - - + { - const newMode = id.replace(idPrefix, '') as YAxisMode; - const newYAxisConfigs = [...(layer.yConfig || [])]; - const existingIndex = newYAxisConfigs.findIndex( - (yAxisConfig) => yAxisConfig.forAccessor === accessor - ); - if (existingIndex !== -1) { - newYAxisConfigs[existingIndex].axisMode = newMode; - } else { - newYAxisConfigs.push({ - forAccessor: accessor, - axisMode: newMode, - }); - } - setState(updateLayer(state, { ...layer, yConfig: newYAxisConfigs }, index)); - }} - /> - + > + { + const newMode = id.replace(idPrefix, '') as YAxisMode; + const newYAxisConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYAxisConfigs.findIndex( + (yAxisConfig) => yAxisConfig.forAccessor === accessor + ); + if (existingIndex !== -1) { + newYAxisConfigs[existingIndex].axisMode = newMode; + } else { + newYAxisConfigs.push({ + forAccessor: accessor, + axisMode: newMode, + }); + } + setState(updateLayer(state, { ...layer, yConfig: newYAxisConfigs }, index)); + }} + /> + + + <> + { + const newYConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYConfigs.findIndex( + (yConfig) => yConfig.forAccessor === accessor + ); + if (existingIndex !== -1) { + newYConfigs[existingIndex].color = newColor; + } else { + newYConfigs.push({ + forAccessor: accessor, + color: newColor, + axisMode: 'auto', + }); + } + setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); + }} + /> + + + {!!layer.splitAccessor && ( + + + You cannot apply color on layer with break down by. + + + )} + ); } diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 17ed04aa0e9c49..78d6d9771ed16f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -41,6 +41,7 @@ import { parseInterval } from '../../../../../src/plugins/data/common'; import { EmptyPlaceholder } from '../shared_components'; import { desanitizeFilterContext } from '../utils'; import { getAxesConfiguration } from './axes_configuration'; +import { getColorConfig } from './metric_color_configuration'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -269,6 +270,8 @@ export function XYChart({ } : undefined; + const colorConfig = getColorConfig(filteredLayers); + return ( { + if (layer.splitAccessor) { + return null; + } + return colorConfig[accessor]; + }, groupId: yAxesConfiguration.find((axisConfiguration) => axisConfiguration.series.find((currentSeries) => currentSeries.accessor === accessor) )?.groupId, From 92872714b3995ef5c80935c01c0528e731fcac3a Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 30 Jun 2020 18:13:28 +0200 Subject: [PATCH 02/19] refactor: don't read palette yourself --- .../xy_visualization/color_configuration.ts | 15 +++++++ .../metric_color_configuration.ts | 42 ------------------- .../xy_visualization/xy_config_panel.tsx | 19 +++++++-- .../public/xy_visualization/xy_expression.tsx | 11 +---- 4 files changed, 33 insertions(+), 54 deletions(-) create mode 100644 x-pack/plugins/lens/public/xy_visualization/color_configuration.ts delete mode 100644 x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts diff --git a/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts b/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts new file mode 100644 index 00000000000000..def4ed57f10f27 --- /dev/null +++ b/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { LayerConfig, YConfig } from './types'; + +export const getColor = (layer: LayerConfig, accessor: string) => { + if (layer.splitAccessor) { + return null; + } + return ( + layer?.yConfig?.find((yConfig: YConfig) => yConfig.forAccessor === accessor)?.color || null + ); +}; diff --git a/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts b/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts deleted file mode 100644 index 5877b731fe4289..00000000000000 --- a/x-pack/plugins/lens/public/xy_visualization/metric_color_configuration.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { euiPaletteColorBlind } from '@elastic/eui'; -import { LayerConfig, YConfig } from './types'; -const ROTATION_LEN = 10; - -export const getColorConfig = (layers: LayerConfig[]) => { - const palette = euiPaletteColorBlind({ - rotations: layers.filter((l: LayerConfig) => l.splitAccessor).length + 1, - }); - - let counter = 0; - let rotationOffset = 0; - const colorConfig: Record = {}; - - for (let l = 0; l < layers.length; l++) { - const layer = layers[l]; - for (let a = 0; a < layer.accessors.length; a++) { - const accessor = layer.accessors[a]; - colorConfig[accessor] = - layer?.yConfig?.find((yConfig) => yConfig.forAccessor === accessor)?.color || - palette[(counter % ROTATION_LEN) + rotationOffset * ROTATION_LEN]; - counter += 1; - } - if (layer.splitAccessor) { - ++rotationOffset; - counter = 0; - } - } - return colorConfig; -}; - -export const getColorForPanel = (layer: LayerConfig, accessor: string, layers: LayerConfig[]) => { - return ( - layer?.yConfig?.find((yConfig: YConfig) => yConfig.forAccessor === accessor)?.color || - getColorConfig(layers)[accessor] - ); -}; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 0a46f9a575a983..17504404f31705 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -13,12 +13,18 @@ import { EuiForm, EuiColorPicker, EuiCallOut, + EuiInputPopover, + EuiFieldText, + EuiSpacer, + EuiIcon, + EuiFormControlLayout, + EuiColorPickerSwatch, } from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; import { isHorizontalChart, isHorizontalSeries } from './state_helpers'; import { trackUiEvent } from '../lens_ui_telemetry'; -import { getColorForPanel } from './metric_color_configuration'; +import { getColor } from './color_configuration'; type UnwrapArray = T extends Array ? P : T; @@ -91,7 +97,7 @@ export function DimensionEditor({ layer.yConfig?.find((yAxisConfig) => yAxisConfig.forAccessor === accessor)?.axisMode) || 'auto'; - const color = getColorForPanel(layer, accessor, state.layers); + const color = getColor(layer, accessor); return ( <> { const newYConfigs = [...(layer.yConfig || [])]; @@ -172,7 +177,15 @@ export function DimensionEditor({ } setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); }} + color={color} + secondaryInputDisplay="top" + button={} /> + {!!layer.splitAccessor && !color && ( +
default color is displayed, you cannot edit series with split accessor
+ )} + {!layer.splitAccessor && !color &&
default color is displayed
} + {!layer.splitAccessor && color &&
custom color is displayed
}
{!!layer.splitAccessor && ( diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 78d6d9771ed16f..7d3adb50df49d4 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -41,7 +41,7 @@ import { parseInterval } from '../../../../../src/plugins/data/common'; import { EmptyPlaceholder } from '../shared_components'; import { desanitizeFilterContext } from '../utils'; import { getAxesConfiguration } from './axes_configuration'; -import { getColorConfig } from './metric_color_configuration'; +import { getColor } from './color_configuration'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -270,8 +270,6 @@ export function XYChart({ } : undefined; - const colorConfig = getColorConfig(filteredLayers); - return ( { - if (layer.splitAccessor) { - return null; - } - return colorConfig[accessor]; - }, + color: () => getColor(layer, accessor), groupId: yAxesConfiguration.find((axisConfiguration) => axisConfiguration.series.find((currentSeries) => currentSeries.accessor === accessor) )?.groupId, From 8febc84c3ed99eb43fd5c71f63e7863fad342b61 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 30 Jun 2020 18:20:27 +0200 Subject: [PATCH 03/19] compressed picker --- x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 17504404f31705..0f6509da4a7784 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -179,6 +179,7 @@ export function DimensionEditor({ }} color={color} secondaryInputDisplay="top" + compressed={true} button={} /> {!!layer.splitAccessor && !color && ( From cf543048749bf71e0136819e6eb603202af35444 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 17:39:25 +0200 Subject: [PATCH 04/19] feat: custom color Picker --- .../xy_visualization/_xy_expression.scss | 4 + .../xy_visualization/xy_config_panel.tsx | 166 ++++++++++++------ 2 files changed, 120 insertions(+), 50 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss index 579f66f99b9fbf..ba9e690a0a6fd8 100644 --- a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss +++ b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss @@ -10,3 +10,7 @@ align-items: center; justify-content: center; } + +.lnsConfigPanel__colorLayout { + max-width: 172px; +} diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 0f6509da4a7784..30b33d9351fa76 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonGroup, @@ -12,13 +12,10 @@ import { htmlIdGenerator, EuiForm, EuiColorPicker, - EuiCallOut, + EuiToolTip, EuiInputPopover, EuiFieldText, - EuiSpacer, - EuiIcon, EuiFormControlLayout, - EuiColorPickerSwatch, } from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; @@ -97,9 +94,16 @@ export function DimensionEditor({ layer.yConfig?.find((yAxisConfig) => yAxisConfig.forAccessor === accessor)?.axisMode) || 'auto'; - const color = getColor(layer, accessor); return ( + + + - - <> - { - const newYConfigs = [...(layer.yConfig || [])]; - const existingIndex = newYConfigs.findIndex( - (yConfig) => yConfig.forAccessor === accessor - ); - if (existingIndex !== -1) { - newYConfigs[existingIndex].color = newColor; - } else { - newYConfigs.push({ - forAccessor: accessor, - color: newColor, - axisMode: 'auto', - }); - } - setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); - }} - color={color} - secondaryInputDisplay="top" - compressed={true} - button={} - /> - {!!layer.splitAccessor && !color && ( -
default color is displayed, you cannot edit series with split accessor
- )} - {!layer.splitAccessor && !color &&
default color is displayed
} - {!layer.splitAccessor && color &&
custom color is displayed
} - -
- {!!layer.splitAccessor && ( - - - You cannot apply color on layer with break down by. - - - )}
); } + +const tooltipContent = { + auto: i18n.translate('xpack.lens.configPanel.color.tooltip.auto', { + defaultMessage: 'Lens automatically picks colors for you unless you specify a custom color.', + }), + custom: i18n.translate('xpack.lens.configPanel.color.tooltip.custom', { + defaultMessage: 'Clear the custom color to return to “Auto” mode.', + }), + disabled: i18n.translate('xpack.lens.configPanel.color.tooltip.disabled', { + defaultMessage: + 'Individual series cannot be custom colored when the layer includes a “Split by.“', + }), +}; + +const autoMessage = i18n.translate('xpack.lens.configPanel.color.auto', { + defaultMessage: 'Auto', +}); + +const DisabledColorPicker = () => ( + + + +); + +const ColorPicker = ({ + state, + setState, + layerId, + accessor, +}: VisualizationDimensionEditorProps) => { + const index = state.layers.findIndex((l) => l.layerId === layerId); + const layer = state.layers[index]; + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + if (layer.splitAccessor) { + return ; + } + + const color = getColor(layer, accessor); + const toggleIsPopoverOpen = (shouldBeOpen = !isPopoverOpen) => { + setIsPopoverOpen(shouldBeOpen); + }; + + const handleColor = (newColor = '') => { + const newYConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); + if (existingIndex !== -1) { + newYConfigs[existingIndex].color = newColor; + } else { + newYConfigs.push({ + forAccessor: accessor, + color: newColor, + axisMode: 'auto', + }); + } + setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); + }; + + return ( + + handleColor() } : undefined} + icon={{ type: 'arrowDown', side: 'right' }} + > + toggleIsPopoverOpen(true)} + icon={{ + type: color ? 'stopFilled' : 'stopSlash', + style: { color: color || 'inherit' }, + }} + className="lnsConfigPanel__colorTextField" + value={color?.toUpperCase() || ''} + placeholder={autoMessage} + aria-label="Use aria labels when no actual label is in use" + /> + + } + isOpen={isPopoverOpen} + closePopover={() => toggleIsPopoverOpen(false)} + display="inlineBlock" + > + + + + ); +}; From 6ab4f36807570a3469e90e6c8396158f68ef4a36 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 17:54:04 +0200 Subject: [PATCH 05/19] typecheck --- .../lens/public/xy_visualization/xy_config_panel.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 30b33d9351fa76..4c79e768c2157e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -81,12 +81,8 @@ export function LayerContextMenu(props: VisualizationLayerWidgetProps) { const idPrefix = htmlIdGenerator()(); -export function DimensionEditor({ - state, - setState, - layerId, - accessor, -}: VisualizationDimensionEditorProps) { +export function DimensionEditor(props: VisualizationDimensionEditorProps) { + const { state, setState, layerId, accessor } = props; const index = state.layers.findIndex((l) => l.layerId === layerId); const layer = state.layers[index]; const axisMode = @@ -102,7 +98,7 @@ export function DimensionEditor({ defaultMessage: 'Series Color', })} > - + Date: Wed, 1 Jul 2020 18:52:55 +0200 Subject: [PATCH 06/19] refactoring & tests --- .../__snapshots__/xy_expression.test.tsx.snap | 14 ++++++++++++++ .../lens/public/xy_visualization/state_helpers.ts | 9 +++++++++ .../public/xy_visualization/xy_config_panel.tsx | 5 ++--- .../lens/public/xy_visualization/xy_expression.tsx | 7 +++---- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap index 48c70e0a4a05b8..0d5efb5012d6dd 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap @@ -35,6 +35,7 @@ exports[`xy_expression XYChart component it renders area 1`] = ` title="a" /> { + if (layer.splitAccessor) { + return null; + } + return ( + layer?.yConfig?.find((yConfig: YConfig) => yConfig.forAccessor === accessor)?.color || null + ); +}; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 4c79e768c2157e..ede453bbc4abd9 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -19,9 +19,8 @@ import { } from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; -import { isHorizontalChart, isHorizontalSeries } from './state_helpers'; +import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers'; import { trackUiEvent } from '../lens_ui_telemetry'; -import { getColor } from './color_configuration'; type UnwrapArray = T extends Array ? P : T; @@ -204,7 +203,7 @@ const ColorPicker = ({ return ; } - const color = getColor(layer, accessor); + const color = getSeriesColor(layer, accessor); const toggleIsPopoverOpen = (shouldBeOpen = !isPopoverOpen) => { setIsPopoverOpen(shouldBeOpen); }; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 7d3adb50df49d4..c30c1453112546 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -34,14 +34,13 @@ import { LensFilterEvent, LensBrushEvent, } from '../types'; -import { XYArgs, SeriesType, visualizationTypes } from './types'; +import { LayerConfig, YConfig, XYArgs, SeriesType, visualizationTypes } from './types'; import { VisualizationContainer } from '../visualization_container'; -import { isHorizontalChart } from './state_helpers'; +import { isHorizontalChart, getSeriesColor } from './state_helpers'; import { parseInterval } from '../../../../../src/plugins/data/common'; import { EmptyPlaceholder } from '../shared_components'; import { desanitizeFilterContext } from '../utils'; import { getAxesConfiguration } from './axes_configuration'; -import { getColor } from './color_configuration'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -431,7 +430,7 @@ export function XYChart({ data: rows, xScaleType, yScaleType, - color: () => getColor(layer, accessor), + color: () => getSeriesColor(layer, accessor), groupId: yAxesConfiguration.find((axisConfiguration) => axisConfiguration.series.find((currentSeries) => currentSeries.accessor === accessor) )?.groupId, From 8b80ff1f034ec8b5a993852dc7a01c4642dda1d7 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 19:20:26 +0200 Subject: [PATCH 07/19] removing caret-color --- .../plugins/lens/public/xy_visualization/_xy_expression.scss | 5 +++++ .../plugins/lens/public/xy_visualization/xy_config_panel.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss index ba9e690a0a6fd8..86a19d6f280f45 100644 --- a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss +++ b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss @@ -14,3 +14,8 @@ .lnsConfigPanel__colorLayout { max-width: 172px; } + +.lnsConfigPanel__colorTextField { + caret-color: transparent; + cursor: pointer; +} \ No newline at end of file diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index ede453bbc4abd9..4630b3d7bf9c72 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -239,7 +239,7 @@ const ColorPicker = ({ toggleIsPopoverOpen(true)} + onFocus={(ev) => toggleIsPopoverOpen(true)} icon={{ type: color ? 'stopFilled' : 'stopSlash', style: { color: color || 'inherit' }, From 9cf9232430fd1eb9ebdcc1526de978a8efe7f4e7 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 20:42:17 +0200 Subject: [PATCH 08/19] aaand back to ColorPicker --- .../xy_visualization/_xy_expression.scss | 9 -- .../xy_visualization/xy_config_panel.tsx | 116 +++++++----------- 2 files changed, 45 insertions(+), 80 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss index 86a19d6f280f45..579f66f99b9fbf 100644 --- a/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss +++ b/x-pack/plugins/lens/public/xy_visualization/_xy_expression.scss @@ -10,12 +10,3 @@ align-items: center; justify-content: center; } - -.lnsConfigPanel__colorLayout { - max-width: 172px; -} - -.lnsConfigPanel__colorTextField { - caret-color: transparent; - cursor: pointer; -} \ No newline at end of file diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 4630b3d7bf9c72..10b0c96970eb11 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -12,11 +12,11 @@ import { htmlIdGenerator, EuiForm, EuiColorPicker, + EuiColorPickerProps, EuiToolTip, - EuiInputPopover, EuiFieldText, - EuiFormControlLayout, } from '@elastic/eui'; +import { useColorPickerState } from '@elastic/eui/lib/services'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers'; @@ -172,23 +172,6 @@ const autoMessage = i18n.translate('xpack.lens.configPanel.color.auto', { defaultMessage: 'Auto', }); -const DisabledColorPicker = () => ( - - - -); - const ColorPicker = ({ state, setState, @@ -197,66 +180,57 @@ const ColorPicker = ({ }: VisualizationDimensionEditorProps) => { const index = state.layers.findIndex((l) => l.layerId === layerId); const layer = state.layers[index]; - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - - if (layer.splitAccessor) { - return ; - } - - const color = getSeriesColor(layer, accessor); - const toggleIsPopoverOpen = (shouldBeOpen = !isPopoverOpen) => { - setIsPopoverOpen(shouldBeOpen); - }; - - const handleColor = (newColor = '') => { - const newYConfigs = [...(layer.yConfig || [])]; - const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); - if (existingIndex !== -1) { - newYConfigs[existingIndex].color = newColor; - } else { - newYConfigs.push({ - forAccessor: accessor, - color: newColor, - axisMode: 'auto', - }); + const disabled = !!layer.splitAccessor; + + const [color, setColor, errors] = useColorPickerState(getSeriesColor(layer, accessor)); + + const handleColor: EuiColorPickerProps['onChange'] = (newColor, output) => { + setColor(newColor, output); + if (output.isValid) { + const newYConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); + if (existingIndex !== -1) { + newYConfigs[existingIndex].color = newColor; + } else { + newYConfigs.push({ + forAccessor: accessor, + color: newColor, + axisMode: 'auto', + }); + } + setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); } - setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); }; return ( - handleColor() } : undefined} - icon={{ type: 'arrowDown', side: 'right' }} - > - toggleIsPopoverOpen(true)} - icon={{ - type: color ? 'stopFilled' : 'stopSlash', - style: { color: color || 'inherit' }, - }} - className="lnsConfigPanel__colorTextField" - value={color?.toUpperCase() || ''} - placeholder={autoMessage} - aria-label="Use aria labels when no actual label is in use" - /> - - } - isOpen={isPopoverOpen} - closePopover={() => toggleIsPopoverOpen(false)} - display="inlineBlock" - > - - + {disabled ? ( + + ) : ( + + )} ); }; From 9f42172df9cb09a1127bc9d0c1475376772c36f4 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 21:12:03 +0200 Subject: [PATCH 09/19] expression fix --- .../xy_visualization/color_configuration.ts | 15 --------------- .../lens/public/xy_visualization/to_expression.ts | 4 ++-- .../public/xy_visualization/xy_config_panel.tsx | 10 +++++++--- 3 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 x-pack/plugins/lens/public/xy_visualization/color_configuration.ts diff --git a/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts b/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts deleted file mode 100644 index def4ed57f10f27..00000000000000 --- a/x-pack/plugins/lens/public/xy_visualization/color_configuration.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { LayerConfig, YConfig } from './types'; - -export const getColor = (layer: LayerConfig, accessor: string) => { - if (layer.splitAccessor) { - return null; - } - return ( - layer?.yConfig?.find((yConfig: YConfig) => yConfig.forAccessor === accessor)?.color || null - ); -}; diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 28f6871644d06b..b5b796dc019de1 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -188,8 +188,8 @@ export const buildExpression = ( function: 'lens_xy_yConfig', arguments: { forAccessor: [yConfig.forAccessor], - axisMode: [yConfig.axisMode], - color: [yConfig.color], + axisMode: yConfig.axisMode ? [yConfig.axisMode] : [], + color: yConfig.color ? [yConfig.color] : [], }, }, ], diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 10b0c96970eb11..57d44be2470a17 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -186,16 +186,20 @@ const ColorPicker = ({ const handleColor: EuiColorPickerProps['onChange'] = (newColor, output) => { setColor(newColor, output); - if (output.isValid) { + + if (output.isValid || newColor === '') { const newYConfigs = [...(layer.yConfig || [])]; const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); if (existingIndex !== -1) { - newYConfigs[existingIndex].color = newColor; + if (newColor === '') { + delete newYConfigs[existingIndex].color; + } else { + newYConfigs[existingIndex].color = newColor; + } } else { newYConfigs.push({ forAccessor: accessor, color: newColor, - axisMode: 'auto', }); } setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); From 4720a987037f604154249de53fc29d8cd3cde86c Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 21:23:19 +0200 Subject: [PATCH 10/19] color fix --- .../lens/public/xy_visualization/xy_config_panel.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 57d44be2470a17..eb0b1265b66c7c 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -184,22 +184,22 @@ const ColorPicker = ({ const [color, setColor, errors] = useColorPickerState(getSeriesColor(layer, accessor)); - const handleColor: EuiColorPickerProps['onChange'] = (newColor, output) => { - setColor(newColor, output); + const handleColor: EuiColorPickerProps['onChange'] = (text, output) => { + setColor(text, output); - if (output.isValid || newColor === '') { + if (output.isValid || text === '') { const newYConfigs = [...(layer.yConfig || [])]; const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); if (existingIndex !== -1) { - if (newColor === '') { + if (text === '') { delete newYConfigs[existingIndex].color; } else { - newYConfigs[existingIndex].color = newColor; + newYConfigs[existingIndex].color = output.hex; } } else { newYConfigs.push({ forAccessor: accessor, - color: newColor, + color: output.hex, }); } setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); From 6a54049f064d80f4b883b86a6fc6d7d3b9e35a3d Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 22:26:26 +0200 Subject: [PATCH 11/19] tests added to xy_expression --- .../public/xy_visualization/state_helpers.ts | 2 +- .../xy_visualization/xy_expression.test.tsx | 69 +++++++++++++++++++ .../public/xy_visualization/xy_expression.tsx | 2 +- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts index ee21743c1120cd..2ddb9418abad9d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts +++ b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts @@ -5,7 +5,7 @@ */ import { EuiIconType } from '@elastic/eui/src/components/icon/icon'; -import { SeriesType, visualizationTypes } from './types'; +import { SeriesType, visualizationTypes, LayerConfig, YConfig } from './types'; export function isHorizontalSeries(seriesType: SeriesType) { return seriesType === 'bar_horizontal' || seriesType === 'bar_horizontal_stacked'; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 34f2a9111253b7..2276d5671620c9 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -993,6 +993,75 @@ describe('xy_expression', () => { }); }); + describe('y series coloring', () => { + test('color is applied to chart for multiple series', () => { + const args = createArgsWithLayers(); + const newArgs = { + ...args, + layers: [ + { + ...args.layers[0], + splitAccessor: undefined, + accessors: ['a', 'b'], + yConfig: [ + { + forAccessor: 'a', + color: '#550000', + }, + { + forAccessor: 'b', + color: '#FFFF00', + }, + ], + }, + { + ...args.layers[0], + splitAccessor: undefined, + accessors: ['c'], + yConfig: [ + { + forAccessor: 'c', + color: '#FEECDF', + }, + ], + }, + ], + } as XYArgs; + + const component = getRenderedComponent(dataWithoutFormats, newArgs); + expect(component.find(LineSeries).at(0).prop('color')!()).toEqual('#550000'); + expect(component.find(LineSeries).at(1).prop('color')!()).toEqual('#FFFF00'); + expect(component.find(LineSeries).at(2).prop('color')!()).toEqual('#FEECDF'); + }); + test('color is not applied to chart when splitAccessor is defined or when not configured', () => { + const args = createArgsWithLayers(); + const newArgs = { + ...args, + layers: [ + { + ...args.layers[0], + accessors: ['a'], + yConfig: [ + { + forAccessor: 'a', + color: '#550000', + }, + ], + }, + { + ...args.layers[0], + splitAccessor: undefined, + accessors: ['c'], + }, + ], + } as XYArgs; + + const component = getRenderedComponent(dataWithoutFormats, newArgs); + expect(component.find(LineSeries).at(0).prop('color')!()).toEqual(null); + expect(component.find(LineSeries).at(1).prop('color')!()).toEqual(null); + }); + }); + describe('provides correct series naming', () => { const nameFnArgs = { seriesKeys: [], diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index c30c1453112546..1f43a4117db0c5 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -34,7 +34,7 @@ import { LensFilterEvent, LensBrushEvent, } from '../types'; -import { LayerConfig, YConfig, XYArgs, SeriesType, visualizationTypes } from './types'; +import { XYArgs, SeriesType, visualizationTypes } from './types'; import { VisualizationContainer } from '../visualization_container'; import { isHorizontalChart, getSeriesColor } from './state_helpers'; import { parseInterval } from '../../../../../src/plugins/data/common'; From 144cf1b68a4a376e0c7bf82106770d7532783e78 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 1 Jul 2020 22:44:05 +0200 Subject: [PATCH 12/19] types --- .../lens/public/xy_visualization/xy_config_panel.tsx | 12 +++--------- .../public/xy_visualization/xy_expression.test.tsx | 12 ++++++------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index eb0b1265b66c7c..cb5bf16cc90ea4 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -16,7 +16,6 @@ import { EuiToolTip, EuiFieldText, } from '@elastic/eui'; -import { useColorPickerState } from '@elastic/eui/lib/services'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers'; @@ -182,10 +181,10 @@ const ColorPicker = ({ const layer = state.layers[index]; const disabled = !!layer.splitAccessor; - const [color, setColor, errors] = useColorPickerState(getSeriesColor(layer, accessor)); + const [color, setColor] = useState(getSeriesColor(layer, accessor)); const handleColor: EuiColorPickerProps['onChange'] = (text, output) => { - setColor(text, output); + setColor(text); if (output.isValid || text === '') { const newYConfigs = [...(layer.yConfig || [])]; @@ -228,12 +227,7 @@ const ColorPicker = ({ aria-label="Color picker disabled" /> ) : ( - + )} ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 2276d5671620c9..472b48491886b2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -1029,11 +1029,11 @@ describe('xy_expression', () => { } as XYArgs; const component = getRenderedComponent(dataWithoutFormats, newArgs); - expect(component.find(LineSeries).at(0).prop('color')!()).toEqual('#550000'); - expect(component.find(LineSeries).at(1).prop('color')!()).toEqual('#FFFF00'); - expect(component.find(LineSeries).at(2).prop('color')!()).toEqual('#FEECDF'); + expect((component.find(LineSeries).at(0).prop('color') as Function)!()).toEqual('#550000'); + expect((component.find(LineSeries).at(1).prop('color') as Function)!()).toEqual('#FFFF00'); + expect((component.find(LineSeries).at(2).prop('color') as Function)!()).toEqual('#FEECDF'); }); - test('color is not applied to chart when splitAccessor is defined or when not configured', () => { + test('color is not applied to chart when splitAccessor is defined or when yConfig is not configured', () => { const args = createArgsWithLayers(); const newArgs = { ...args, @@ -1057,8 +1057,8 @@ describe('xy_expression', () => { } as XYArgs; const component = getRenderedComponent(dataWithoutFormats, newArgs); - expect(component.find(LineSeries).at(0).prop('color')!()).toEqual(null); - expect(component.find(LineSeries).at(1).prop('color')!()).toEqual(null); + expect((component.find(LineSeries).at(0).prop('color') as Function)!()).toEqual(null); + expect((component.find(LineSeries).at(1).prop('color') as Function)!()).toEqual(null); }); }); From 71ce1602d5353ceb4c0255c4a5aa077e701da9c4 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 2 Jul 2020 08:32:31 +0200 Subject: [PATCH 13/19] design review --- .../xy_visualization/xy_config_panel.tsx | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index cb5bf16cc90ea4..47010cdde83106 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -92,14 +92,16 @@ export function DimensionEditor(props: VisualizationDimensionEditorProps) - {disabled ? ( - - ) : ( - - )} + ); }; From a3fb6b73494a1984a52ffa37e1cd7dffa801b0f1 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 2 Jul 2020 09:50:23 +0200 Subject: [PATCH 14/19] types --- .../plugins/lens/public/xy_visualization/xy_config_panel.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 47010cdde83106..3c0c3453915cb1 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -14,7 +14,6 @@ import { EuiColorPicker, EuiColorPickerProps, EuiToolTip, - EuiFieldText, } from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; @@ -169,10 +168,6 @@ const tooltipContent = { }), }; -const autoMessage = i18n.translate('xpack.lens.configPanel.color.auto', { - defaultMessage: 'Auto', -}); - const ColorPicker = ({ state, setState, From b8aa3645028493142ae231f3c414bb2b9c269aa7 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 2 Jul 2020 11:29:37 +0200 Subject: [PATCH 15/19] addressing Joe's comment --- .../xy_visualization/xy_config_panel.tsx | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 3c0c3453915cb1..0e3c9c21aa4144 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -6,6 +6,7 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { debounce } from 'lodash'; import { EuiButtonGroup, EuiFormRow, @@ -164,7 +165,7 @@ const tooltipContent = { }), disabled: i18n.translate('xpack.lens.configPanel.color.tooltip.disabled', { defaultMessage: - 'Individual series cannot be custom colored when the layer includes a “Split by.“', + 'Individual series cannot be custom colored when the layer includes a “Break down by“', }), }; @@ -182,25 +183,28 @@ const ColorPicker = ({ const handleColor: EuiColorPickerProps['onChange'] = (text, output) => { setColor(text); - if (output.isValid || text === '') { - const newYConfigs = [...(layer.yConfig || [])]; - const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); - if (existingIndex !== -1) { - if (text === '') { - delete newYConfigs[existingIndex].color; - } else { - newYConfigs[existingIndex].color = output.hex; - } + updateColorInState(text, output); + } + }; + + const updateColorInState: EuiColorPickerProps['onChange'] = debounce((text, output) => { + const newYConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); + if (existingIndex !== -1) { + if (text === '') { + delete newYConfigs[existingIndex].color; } else { - newYConfigs.push({ - forAccessor: accessor, - color: output.hex, - }); + newYConfigs[existingIndex].color = output.hex; } - setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); + } else { + newYConfigs.push({ + forAccessor: accessor, + color: output.hex, + }); } - }; + setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); + }, 256); return ( Date: Thu, 2 Jul 2020 13:23:36 +0200 Subject: [PATCH 16/19] +memo --- .../xy_visualization/xy_config_panel.tsx | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 0e3c9c21aa4144..e83d3f51c91fa7 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -188,23 +188,27 @@ const ColorPicker = ({ } }; - const updateColorInState: EuiColorPickerProps['onChange'] = debounce((text, output) => { - const newYConfigs = [...(layer.yConfig || [])]; - const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); - if (existingIndex !== -1) { - if (text === '') { - delete newYConfigs[existingIndex].color; - } else { - newYConfigs[existingIndex].color = output.hex; - } - } else { - newYConfigs.push({ - forAccessor: accessor, - color: output.hex, - }); - } - setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); - }, 256); + const updateColorInState: EuiColorPickerProps['onChange'] = React.useMemo( + () => + debounce((text, output) => { + const newYConfigs = [...(layer.yConfig || [])]; + const existingIndex = newYConfigs.findIndex((yConfig) => yConfig.forAccessor === accessor); + if (existingIndex !== -1) { + if (text === '') { + delete newYConfigs[existingIndex].color; + } else { + newYConfigs[existingIndex].color = output.hex; + } + } else { + newYConfigs.push({ + forAccessor: accessor, + color: output.hex, + }); + } + setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); + }, 256), + [state, layer, accessor, index] + ); return ( Date: Thu, 2 Jul 2020 16:02:32 +0200 Subject: [PATCH 17/19] tooltip design change --- .../xy_visualization/xy_config_panel.tsx | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index e83d3f51c91fa7..f28f670404dd03 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -15,6 +15,7 @@ import { EuiColorPicker, EuiColorPickerProps, EuiToolTip, + EuiIcon, } from '@elastic/eui'; import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; import { VisualizationDimensionEditorProps, VisualizationLayerWidgetProps } from '../types'; @@ -90,15 +91,8 @@ export function DimensionEditor(props: VisualizationDimensionEditorProps) return ( - - - + + + + {i18n.translate('xpack.lens.xyChart.seriesColor.label', { + defaultMessage: 'Series color', + })}{' '} + + + } - delay="long" - anchorClassName="eui-displayBlock" > - - + {disabled ? ( + + + + ) : ( + + )} + ); }; From 20a9a40377e6e2e7302eecfda28ecaf742e47383 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 2 Jul 2020 23:07:37 +0200 Subject: [PATCH 18/19] cr --- .../lens/public/xy_visualization/xy_config_panel.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index f28f670404dd03..26908fcf8ae513 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -106,6 +106,7 @@ export function DimensionEditor(props: VisualizationDimensionEditorProps) })} name="axisSide" buttonSize="compressed" + fullWidth className="eui-displayInlineBlock" options={[ { @@ -218,13 +219,18 @@ const ColorPicker = ({ {i18n.translate('xpack.lens.xyChart.seriesColor.label', { defaultMessage: 'Series color', })}{' '} - + } > {disabled ? ( - + Date: Fri, 3 Jul 2020 09:20:10 +0200 Subject: [PATCH 19/19] removing non existing prop --- x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 26908fcf8ae513..e6c284f09ab4e6 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -106,7 +106,6 @@ export function DimensionEditor(props: VisualizationDimensionEditorProps) })} name="axisSide" buttonSize="compressed" - fullWidth className="eui-displayInlineBlock" options={[ {