From 749bfb0969d0d58feb92fada4d61e859c20c36e9 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 12 Nov 2020 16:01:52 +0200 Subject: [PATCH 001/111] es lint fix --- src/plugins/vis_type_pie/README.md | 1 + src/plugins/vis_type_pie/kibana.json | 8 + src/plugins/vis_type_pie/public/chart.scss | 6 + .../vis_type_pie/public/editor/collections.ts | 53 +++ .../public/editor/components/index.tsx | 26 ++ .../public/editor/components/pie.tsx | 104 ++++++ .../editor/components/truncate_labels.tsx | 53 +++ .../vis_type_pie/public/editor/index.ts | 21 ++ src/plugins/vis_type_pie/public/index.ts | 21 ++ .../vis_type_pie/public/pie_component.tsx | 349 ++++++++++++++++++ src/plugins/vis_type_pie/public/pie_fn.ts | 73 ++++ .../vis_type_pie/public/pie_renderer.tsx | 63 ++++ src/plugins/vis_type_pie/public/plugin.ts | 62 ++++ src/plugins/vis_type_pie/public/services.ts | 47 +++ .../vis_type_pie/public/to_ast.test.ts | 60 +++ src/plugins/vis_type_pie/public/to_ast.ts | 50 +++ .../vis_type_pie/public/to_ast_esaggs.ts | 39 ++ .../vis_type_pie/public/types/index.ts | 19 + .../vis_type_pie/public/types/params.ts | 73 ++++ .../vis_type_pie/public/vis_type/index.ts | 22 ++ .../vis_type_pie/public/vis_type/pie.ts | 101 +++++ src/plugins/vis_type_vislib/public/plugin.ts | 5 +- 22 files changed, 1254 insertions(+), 2 deletions(-) create mode 100644 src/plugins/vis_type_pie/README.md create mode 100644 src/plugins/vis_type_pie/kibana.json create mode 100644 src/plugins/vis_type_pie/public/chart.scss create mode 100644 src/plugins/vis_type_pie/public/editor/collections.ts create mode 100644 src/plugins/vis_type_pie/public/editor/components/index.tsx create mode 100644 src/plugins/vis_type_pie/public/editor/components/pie.tsx create mode 100644 src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx create mode 100644 src/plugins/vis_type_pie/public/editor/index.ts create mode 100644 src/plugins/vis_type_pie/public/index.ts create mode 100644 src/plugins/vis_type_pie/public/pie_component.tsx create mode 100644 src/plugins/vis_type_pie/public/pie_fn.ts create mode 100644 src/plugins/vis_type_pie/public/pie_renderer.tsx create mode 100644 src/plugins/vis_type_pie/public/plugin.ts create mode 100644 src/plugins/vis_type_pie/public/services.ts create mode 100644 src/plugins/vis_type_pie/public/to_ast.test.ts create mode 100644 src/plugins/vis_type_pie/public/to_ast.ts create mode 100644 src/plugins/vis_type_pie/public/to_ast_esaggs.ts create mode 100644 src/plugins/vis_type_pie/public/types/index.ts create mode 100644 src/plugins/vis_type_pie/public/types/params.ts create mode 100644 src/plugins/vis_type_pie/public/vis_type/index.ts create mode 100644 src/plugins/vis_type_pie/public/vis_type/pie.ts diff --git a/src/plugins/vis_type_pie/README.md b/src/plugins/vis_type_pie/README.md new file mode 100644 index 00000000000000..0744c9aa3a44c7 --- /dev/null +++ b/src/plugins/vis_type_pie/README.md @@ -0,0 +1 @@ +Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Charts Library advanced setting. \ No newline at end of file diff --git a/src/plugins/vis_type_pie/kibana.json b/src/plugins/vis_type_pie/kibana.json new file mode 100644 index 00000000000000..6b661b817258ea --- /dev/null +++ b/src/plugins/vis_type_pie/kibana.json @@ -0,0 +1,8 @@ +{ + "id": "visTypePie", + "version": "kibana", + "ui": true, + "requiredPlugins": ["charts", "data", "expressions", "visualizations"], + "requiredBundles": ["kibanaUtils", "visDefaultEditor"] + } + \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss new file mode 100644 index 00000000000000..239ee8a60ec9f6 --- /dev/null +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -0,0 +1,6 @@ +.pieChart__container { + width: 100%; + height: 100%; + position: relative; + } + \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts new file mode 100644 index 00000000000000..40c854a502ac92 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { Position } from '@elastic/charts'; + +export const getPositions = () => [ + { + text: i18n.translate('visTypePie.legendPositions.topText', { + defaultMessage: 'Top', + }), + value: Position.Top, + }, + { + text: i18n.translate('visTypePie.legendPositions.leftText', { + defaultMessage: 'Left', + }), + value: Position.Left, + }, + { + text: i18n.translate('visTypePie.legendPositions.rightText', { + defaultMessage: 'Right', + }), + value: Position.Right, + }, + { + text: i18n.translate('visTypePie.legendPositions.bottomText', { + defaultMessage: 'Bottom', + }), + value: Position.Bottom, + }, +]; + +export const getConfigCollections = () => ({ + legendPositions: getPositions(), + positions: getPositions(), +}); diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx new file mode 100644 index 00000000000000..893fdaf2d01a7f --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; +import { PieVisParams } from '../../types'; + +const PieOptionsLazy = lazy(() => import('./pie')); + +export const PieOptions = (props: VisOptionsProps) => ; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx new file mode 100644 index 00000000000000..b893b4913ee461 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -0,0 +1,104 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; + +import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; +import { TruncateLabelsOption } from './truncate_labels'; +import { BasicOptions, SwitchOption } from '../../../../charts/public'; +import { PieVisParams } from '../../types'; + +function PieOptions(props: VisOptionsProps) { + const { stateParams, setValue } = props; + const setLabels = ( + paramName: T, + value: PieVisParams['labels'][T] + ) => setValue('labels', { ...stateParams.labels, [paramName]: value }); + + return ( + <> + + +

+ +

+
+ + + +
+ + + + + +

+ +

+
+ + + + + +
+ + ); +} + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { PieOptions as default }; diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx new file mode 100644 index 00000000000000..6f55f6f070d004 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { ChangeEvent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFormRow, EuiFieldNumber } from '@elastic/eui'; + +interface TruncateLabelsOptionProps { + disabled?: boolean; + value?: number | null; + setValue: (paramName: 'truncate', value: null | number) => void; +} + +function TruncateLabelsOption({ disabled, value = null, setValue }: TruncateLabelsOptionProps) { + const onChange = (ev: ChangeEvent) => + setValue('truncate', ev.target.value === '' ? null : parseFloat(ev.target.value)); + + return ( + + + + ); +} + +export { TruncateLabelsOption }; diff --git a/src/plugins/vis_type_pie/public/editor/index.ts b/src/plugins/vis_type_pie/public/editor/index.ts new file mode 100644 index 00000000000000..2a73b1ad8fa687 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './collections'; +export * from './components'; diff --git a/src/plugins/vis_type_pie/public/index.ts b/src/plugins/vis_type_pie/public/index.ts new file mode 100644 index 00000000000000..2ab0f0127e0687 --- /dev/null +++ b/src/plugins/vis_type_pie/public/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { VisTypePiePlugin } from './plugin'; + +export const plugin = () => new VisTypePiePlugin(); diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx new file mode 100644 index 00000000000000..1d549b49af2cbe --- /dev/null +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -0,0 +1,349 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { + BaseSyntheticEvent, + KeyboardEvent, + memo, + useCallback, + useMemo, + useState, +} from 'react'; +import { uniq } from 'lodash'; + +import { + Chart, + Datum, + LayerValue, + Partition, + PartitionConfig, + PartitionLayer, + PartitionLayout, + PartitionFillLabel, + RecursivePartial, + Position, + Settings, + RenderChangeListener, + ElementClickListener, +} from '@elastic/charts'; +import { keys } from '@elastic/eui'; +import { SeriesLayer } from '../../charts/public'; + +// import { +// getFilterFromChartClickEventFn, +// getFilterFromSeriesFn, +// LegendToggle, +// getBrushFromChartBrushEventFn, +// ClickTriggerEvent, +// } from '../../charts/public'; +import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; + +import { PieVisParams } from './types'; +import { getThemeService, getColorsService, getFormatService } from './services'; +// import { colorSchemas } from 'src/plugins/charts/public'; +// import { ChartType } from '../common'; + +import './chart.scss'; + +export interface PieComponentProps { + visParams: PieVisParams; + visData: Datatable; + uiState: IInterpreterRenderHandlers['uiState']; + fireEvent: IInterpreterRenderHandlers['event']; + renderComplete: IInterpreterRenderHandlers['done']; +} + +export type PieComponentType = typeof PieComponent; + +const EMPTY_SLICE = Symbol('empty_slice'); + +const PieComponent = (props: PieComponentProps) => { + /** + * Stores all series labels to replicate vislib color map lookup + */ + // const allSeries: Array = []; + const chartTheme = getThemeService().useChartsTheme(); + const chartBaseTheme = getThemeService().useChartsBaseTheme(); + const defaultPalette = getColorsService().getAll()[0]; + + const [showLegend, setShowLegend] = useState(() => { + // TODO: Check when this bwc can safely be removed + const bwcLegendStateDefault = + props.visParams.addLegend == null ? true : props.visParams.addLegend; + return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; + }); + + const fillLabel: Partial = { + textInvertible: true, + valueFont: { + fontWeight: 700, + }, + }; + + const onRenderChange = useCallback( + (isRendered) => { + if (isRendered) { + props.renderComplete(); + } + }, + [props] + ); + + const handleFilterClick = useCallback( + (visData: Datatable): ElementClickListener => (elements) => { + // console.log('boom'); + }, + [] + ); + + // const getFilterEventData = useCallback( + // (visData: Datatable, xAccessor: string | number | null) => ( + // series: XYChartSeriesIdentifier + // ): ClickTriggerEvent | null => { + // if (xAccessor !== null) { + // return getFilterFromSeriesFn(visData)(series); + // } + + // return null; + // }, + // [] + // ); + + // const handleFilterAction = useCallback( + // (event: ClickTriggerEvent, negate = false) => { + // props.fireEvent({ + // ...event, + // data: { + // ...event.data, + // negate, + // }, + // }); + // }, + // [props] + // ); + + // const canFilter = async (event: ClickTriggerEvent | null): Promise => { + // if (!event) { + // return false; + // } + // const filters = await getDataActions().createFiltersFromValueClickAction(event.data); + // return Boolean(filters.length); + // }; + + const toggleLegend = useCallback(() => { + setShowLegend((value) => { + const newValue = !value; + props.uiState?.set('vis.legendOpen', newValue); + return newValue; + }); + }, [props.uiState?.set]); + + const setColor = useCallback( + (newColor: string | null, seriesLabel: string | number, event: BaseSyntheticEvent) => { + if ((event as KeyboardEvent).key && (event as KeyboardEvent).key !== keys.ENTER) { + return; + } + + const colors = props.uiState?.get('vis.colors') || {}; + if (colors[seriesLabel] === newColor || !newColor) { + delete colors[seriesLabel]; + } else { + colors[seriesLabel] = newColor; + } + props.uiState?.setSilent('vis.colors', null); + props.uiState?.set('vis.colors', colors); + props.uiState?.emit('colorChanged'); + }, + [props.uiState?.emit, props.uiState?.get, props.uiState?.set, props.uiState?.setSilent] + ); + + const { visData, visParams } = props; + + // console.dir(visData); + // console.dir(visParams); + + // const config = getConfig(visData, visParams); + // const legendPosition = useMemo(() => config.legend.position ?? Position.Right, [ + // config.legend.position, + // ]); + // const timeZone = getTimeZone(); + // const xDomain = + // config.xAxis.scale.type === ScaleType.Ordinal ? undefined : getXDomain(config.aspects.x.params); + // const hasBars = visParams.seriesParams.some( + // ({ type, data: { id: paramId } }) => + // type === ChartType.Histogram && config.aspects.y.find(({ aggId }) => aggId === paramId) + // ); + // const adjustedXDomain = + // config.xAxis.scale.type === ScaleType.Ordinal + // ? undefined + // : getAdjustedDomain(visData.rows, config.aspects.x, timeZone, xDomain, hasBars); + // const legendPosition = useMemo(() => config.legend.position ?? Position.Right, [ + // config.legend.position, + // ]); + // const isDarkMode = getThemeService().useDarkMode(); + // const getSeriesName = getSeriesNameFn(config.aspects, config.aspects.y.length > 1); + + // const getSeriesColor = useCallback( + // (series: XYChartSeriesIdentifier) => { + // const seriesName = getSeriesName(series); + // if (!seriesName) { + // return; + // } + + // const overwriteColors: Record = props.uiState?.get('vis.colors', {}); + + // allSeries.push(seriesName); + // return getColorsService().createColorLookupFunction(allSeries, overwriteColors)(seriesName); + // }, + // [allSeries, getSeriesName, props.uiState?.get] + // ); + + function getSliceValue(d: Datum, metricColumn: DatatableColumn) { + if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { + return d[metricColumn.id]; + } + return Number.EPSILON; + } + + const config: RecursivePartial = { + partitionLayout: PartitionLayout.sunburst, + fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, + outerSizeRatio: 1, + specialFirstInnermostSector: true, + clockwiseSectors: false, + minFontSize: 10, + maxFontSize: 16, + linkLabel: { + maxCount: 5, + fontSize: 11, + textColor: chartTheme.axes?.axisTitle?.fill, + }, + sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill, + sectorLineWidth: 1.5, + circlePadding: 4, + emptySizeRatio: visParams.isDonut ? 0.3 : 0, + }; + + const metricColumn = visData.columns[visParams.dimensions.metric.accessor]; + const metricFieldFormatter = getFormatService().deserialize(visParams.dimensions.metric.format); + const percentFormatter = getFormatService().deserialize({ + id: 'percent', + params: { + pattern: '0.[00]%', + }, + }); + + const bucketColumns: DatatableColumn[] = []; + if (visParams.dimensions.buckets) { + visParams.dimensions.buckets.forEach((b) => { + bucketColumns.push(visData.columns[b.accessor]); + }); + } else { + bucketColumns.push(visData.columns[0]); + } + + const totalSeriesCount = uniq( + visData.rows.map((row) => { + return bucketColumns.map(({ id: columnId }) => row[columnId]).join(','); + }) + ).length; + + const layers: PartitionLayer[] = bucketColumns.map((col) => { + return { + groupByRollup: (d: Datum) => d[col.id] ?? EMPTY_SLICE, + showAccessor: (d: Datum) => d !== EMPTY_SLICE, + nodeLabel: (d: unknown) => { + if (!visParams.labels.show || d === EMPTY_SLICE) { + return ''; + } + // if (col.meta.params) { + // return getFormatService().deserialize(col.format).convert(d) ?? ''; + // } + return String(d); + }, + fillLabel, + shape: { + fillColor: (d) => { + const seriesLayers: SeriesLayer[] = []; + + // Color is determined by round-robin on the index of the innermost slice + // This has to be done recursively until we get to the slice index + let tempParent: typeof d | typeof d['parent'] = d; + while (tempParent.parent && tempParent.depth > 0) { + seriesLayers.unshift({ + name: String(tempParent.parent.children[tempParent.sortIndex][0]), + rankAtDepth: tempParent.sortIndex, + totalSeriesAtDepth: tempParent.parent.children.length, + }); + tempParent = tempParent.parent; + } + + const outputColor = defaultPalette.getColor(seriesLayers, { + behindText: true, + maxDepth: visData.columns.length, + totalSeries: totalSeriesCount, + }); + + return outputColor || 'rgba(0,0,0,0)'; + }, + }, + }; + }); + + return ( +
+ {/* */} + + { + // const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); + + // onClickValue(desanitizeFilterContext(context)); + // }} + onElementClick={handleFilterClick(visData)} + theme={chartTheme} + baseTheme={chartBaseTheme} + /> + getSliceValue(d, metricColumn)} + percentFormatter={(d: number) => percentFormatter.convert(d / 100)} + valueGetter={!visParams.labels.show ? undefined : 'percent'} + valueFormatter={(d: number) => + !visParams.labels.show ? '' : metricFieldFormatter.convert(d) + } + layers={layers} + config={config} + topGroove={!visParams.labels.show ? 0 : undefined} + /> + +
+ ); +}; + +// eslint-disable-next-line import/no-default-export +export default memo(PieComponent); diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts new file mode 100644 index 00000000000000..6123a2e7d32463 --- /dev/null +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; +import { PieVisParams } from './types'; + +export const vislibPieName = 'pie_vis'; + +interface Arguments { + visConfig: string; +} + +export interface RenderValue { + visData: Datatable; + visType: string; + visConfig: PieVisParams; +} + +export type VisTypePieExpressionFunctionDefinition = ExpressionFunctionDefinition< + typeof vislibPieName, + Datatable, + Arguments, + Render +>; + +export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ + name: vislibPieName, + type: 'render', + inputTypes: ['datatable'], + help: i18n.translate('visTypePie.functions.help', { + defaultMessage: 'Pie visualization', + }), + args: { + visConfig: { + types: ['string'], + default: '"{}"', + help: 'vislib pie vis config', + }, + }, + fn(context, args) { + const visConfig = JSON.parse(args.visConfig) as PieVisParams; + + return { + type: 'render', + as: vislibPieName, + value: { + visData: context, + visConfig, + visType: 'pie', + params: { + listenOnChange: true, + }, + }, + }; + }, +}); diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx new file mode 100644 index 00000000000000..baaec8902c5b29 --- /dev/null +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { ExpressionRenderDefinition } from '../../expressions/public'; +import { VisualizationContainer } from '../../visualizations/public'; +// import { SplitChartWarning } from './components'; + +import { RenderValue, vislibPieName } from './pie_fn'; + +const PieComponent = lazy(() => import('./pie_component')); + +function shouldShowNoResultsMessage(visData: any): boolean { + const rows: object[] | undefined = visData?.rows; + const isZeroHits = visData?.hits === 0 || (rows && !rows.length); + + return Boolean(isZeroHits); +} + +export const pieVisRenderer: ExpressionRenderDefinition = { + name: vislibPieName, + displayName: 'Pie visualization', + reuseDomNode: true, + render: (domNode, { visConfig, visData }, handlers) => { + const showNoResult = shouldShowNoResultsMessage(visData); + const isSplitChart = Boolean(visConfig.dimensions.splitRow); + + handlers.onDestroy(() => unmountComponentAtNode(domNode)); + render( + <> + {/* {isSplitChart && } */} + + + + , + domNode + ); + }, +}; diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts new file mode 100644 index 00000000000000..f29e677bcf12df --- /dev/null +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { CoreSetup, CoreStart } from 'src/core/public'; +import { VisualizationsSetup } from '../../visualizations/public'; +import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; +import { ChartsPluginSetup } from '../../charts/public'; +import { DataPublicPluginStart } from '../../data/public'; +import { createPieVisFn } from './pie_fn'; +import { pieVisRenderer } from './pie_renderer'; +import { pieVisTypeDefinition } from './vis_type'; +import { setThemeService, setColorsService, setFormatService } from './services'; + +export interface VisTypePieSetupDependencies { + visualizations: VisualizationsSetup; + expressions: ReturnType; + charts: ChartsPluginSetup; +} + +export interface VisTypePiePluginStartDependencies { + data: DataPublicPluginStart; +} + +export class VisTypePiePlugin { + setup( + core: CoreSetup, + { expressions, visualizations, charts }: VisTypePieSetupDependencies + ) { + // temporary, add it as arg to pieVisRenderer + setThemeService(charts.theme); + // setColorsService(charts.palettes); + charts.palettes.getPalettes().then((palettes) => { + setColorsService(palettes); + }); + + [createPieVisFn].forEach(expressions.registerFunction); + expressions.registerRenderer(pieVisRenderer); + visualizations.createBaseVisualization(pieVisTypeDefinition); + // core.getStartServices().then(([coreStart]) => { + // visualizations.registerAlias(getLensAliasConfig(coreStart.docLinks)); + // }); + } + + start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) { + setFormatService(data.fieldFormats); + } +} diff --git a/src/plugins/vis_type_pie/public/services.ts b/src/plugins/vis_type_pie/public/services.ts new file mode 100644 index 00000000000000..e2b2ef5ba65ba6 --- /dev/null +++ b/src/plugins/vis_type_pie/public/services.ts @@ -0,0 +1,47 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CoreSetup } from '../../../core/public'; +import { createGetterSetter } from '../../kibana_utils/public'; +import { DataPublicPluginStart } from '../../data/public'; +import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; + +export const [getUISettings, setUISettings] = createGetterSetter( + 'pie core.uiSettings' +); + +export const [getDataActions, setDataActions] = createGetterSetter< + DataPublicPluginStart['actions'] +>('pie data.actions'); + +export const [getFormatService, setFormatService] = createGetterSetter< + DataPublicPluginStart['fieldFormats'] +>('pie data.fieldFormats'); + +export const [getTimefilter, setTimefilter] = createGetterSetter< + DataPublicPluginStart['query']['timefilter']['timefilter'] +>('pie data.query.timefilter.timefilter'); + +export const [getThemeService, setThemeService] = createGetterSetter( + 'pie charts.theme' +); + +export const [getColorsService, setColorsService] = createGetterSetter( + 'pie charts.color' +); diff --git a/src/plugins/vis_type_pie/public/to_ast.test.ts b/src/plugins/vis_type_pie/public/to_ast.test.ts new file mode 100644 index 00000000000000..614475a2ca622c --- /dev/null +++ b/src/plugins/vis_type_pie/public/to_ast.test.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from '../../visualizations/public'; +import { buildExpression } from '../../expressions/public'; + +import { PieVisParams } from './types'; +import { samplePieVis } from '../../vis_type_vislib/public/sample_vis.test.mocks'; +import { toExpressionAst } from './to_ast'; + +jest.mock('../../expressions/public', () => ({ + ...(jest.requireActual('../../expressions/public') as any), + buildExpression: jest.fn().mockImplementation(() => ({ + toAst: () => ({ + type: 'expression', + chain: [], + }), + })), +})); + +jest.mock('./to_ast_esaggs', () => ({ + getEsaggsFn: jest.fn(), +})); + +describe('pie vis toExpressionAst function', () => { + let vis: Vis; + + const params = { + timefilter: {}, + timeRange: {}, + abortSignal: {}, + } as any; + + beforeEach(() => { + vis = samplePieVis as any; + }); + + it('should match basic snapshot', () => { + toExpressionAst(vis, params); + const [, builtExpression] = (buildExpression as jest.Mock).mock.calls[0][0]; + + expect(builtExpression).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts new file mode 100644 index 00000000000000..7dfe03fed84c9c --- /dev/null +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getVisSchemas, VisToExpressionAst } from '../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; + +import { PieVisParams } from './types'; +import { vislibPieName, VisTypePieExpressionFunctionDefinition } from './pie_fn'; +import { getEsaggsFn } from './to_ast_esaggs'; + +export const toExpressionAst: VisToExpressionAst = async (vis, params) => { + const schemas = getVisSchemas(vis, params); + const visConfig = { + ...vis.params, + dimensions: { + metric: schemas.metric[0], + buckets: schemas.segment, + splitRow: schemas.split_row, + splitColumn: schemas.split_column, + }, + }; + + const configStr = JSON.stringify(visConfig).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); + const visTypePie = buildExpressionFunction( + vislibPieName, + { + visConfig: configStr, + } + ); + + const ast = buildExpression([getEsaggsFn(vis), visTypePie]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts new file mode 100644 index 00000000000000..047a626032edab --- /dev/null +++ b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from '../../visualizations/public'; +import { buildExpressionFunction } from '../../expressions/public'; +import { EsaggsExpressionFunctionDefinition } from '../../data/public'; + +import { PieVisParams } from './types'; + +/** + * Get esaggs expressions function + * TODO: replace this with vis.data.aggs!.toExpressionAst(); + * @param vis + */ +export function getEsaggsFn(vis: Vis) { + return buildExpressionFunction('esaggs', { + index: vis.data.indexPattern!.id!, + metricsAtAllLevels: vis.isHierarchical(), + partialRows: false, + aggConfigs: JSON.stringify(vis.data.aggs!.aggs), + includeFormatHints: false, + }); +} diff --git a/src/plugins/vis_type_pie/public/types/index.ts b/src/plugins/vis_type_pie/public/types/index.ts new file mode 100644 index 00000000000000..f0cbe26b3fced0 --- /dev/null +++ b/src/plugins/vis_type_pie/public/types/index.ts @@ -0,0 +1,19 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export * from './params'; diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/params.ts new file mode 100644 index 00000000000000..2e2b92dc1e4ee3 --- /dev/null +++ b/src/plugins/vis_type_pie/public/types/params.ts @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Position } from '@elastic/charts'; + +export interface Dimension { + accessor: number; + format: { + id?: string; + params?: { pattern?: string; [key: string]: any }; + }; +} + +export interface Dimensions { + metric: Dimension; + buckets?: Dimension[]; + splitRow?: Dimension[]; + splitColumn?: Dimension[]; +} + +export interface PieVisParams { + type: 'pie'; + addTooltip: boolean; + addLegend: boolean; + legendPosition: Position; + dimensions: Dimensions; + isDonut: boolean; + labels: { + show: boolean; + values: boolean; + last_level: boolean; + truncate: number | null; + }; +} + +export interface Column { + // -1 value can be in a fake X aspect + id: string | -1; + name: string; +} + +export interface Row { + [key: string]: number | string | object; +} + +export interface TableParent { + table: Table; + tables?: Table[]; + column: number; + row: number; + key: number; + name: string; +} +export interface Table { + columns: Column[]; + rows: Row[]; + $parent?: TableParent; +} diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts new file mode 100644 index 00000000000000..c6692073377edf --- /dev/null +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getPieVisTypeDefinition } from './pie'; + +export const pieVisTypeDefinition = getPieVisTypeDefinition(true); diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts new file mode 100644 index 00000000000000..9df2030419e3aa --- /dev/null +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -0,0 +1,101 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +// @ts-ignore +import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; +import { Position } from '@elastic/charts'; + +import { Schemas } from '../../../vis_default_editor/public'; +import { AggGroupNames } from '../../../data/public'; +import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualizations/public'; + +import { PieVisParams } from '../types'; +import { toExpressionAst } from '../to_ast'; +import { getPositions, PieOptions } from '../editor'; + +export const getPieVisTypeDefinition = ( + showElasticChartsOptions = false +): BaseVisTypeOptions => ({ + name: 'pie', + title: i18n.translate('visTypePie.pie.pieTitle', { defaultMessage: 'Pie' }), + icon: 'visPie', + description: i18n.translate('visTypePie.pie.pieDescription', { + defaultMessage: 'Compare parts of a whole', + }), + toExpressionAst, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], + visConfig: { + defaults: { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: Position.Right, + isDonut: true, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, + }, + }, + editorConfig: { + collections: { + legendPositions: getPositions(), + }, + optionsTemplate: PieOptions, + schemas: new Schemas([ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: i18n.translate('visTypeVislib.pie.metricTitle', { + defaultMessage: 'Slice size', + }), + min: 1, + max: 1, + aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], + defaults: [{ schema: 'metric', type: 'count' }], + }, + { + group: AggGroupNames.Buckets, + name: 'segment', + title: i18n.translate('visTypeVislib.pie.segmentTitle', { + defaultMessage: 'Split slices', + }), + min: 0, + max: Infinity, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + }, + { + group: AggGroupNames.Buckets, + name: 'split', + title: i18n.translate('visTypeVislib.pie.splitTitle', { + defaultMessage: 'Split chart', + }), + mustBeFirst: true, + min: 0, + max: 1, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + }, + ]), + }, + hierarchicalData: true, + responseHandler: 'vislib_slices', +}); diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts index f183042fd52012..dcdc36f0c7c043 100644 --- a/src/plugins/vis_type_vislib/public/plugin.ts +++ b/src/plugins/vis_type_vislib/public/plugin.ts @@ -70,9 +70,10 @@ export class VisTypeVislibPlugin } // Register non-converted types visLibVisTypeDefinitions.forEach(visualizations.createBaseVisualization); - visualizations.createBaseVisualization(pieVisTypeDefinition); + // visualizations.createBaseVisualization(pieVisTypeDefinition); expressions.registerRenderer(getVislibVisRenderer(core, charts)); - [createVisTypeVislibVisFn(), createPieVisFn()].forEach(expressions.registerFunction); + // [createVisTypeVislibVisFn(), createPieVisFn()].forEach(expressions.registerFunction); + [createVisTypeVislibVisFn()].forEach(expressions.registerFunction); } public start(core: CoreStart, { data }: VisTypeVislibPluginStartDependencies) { From a3dcef1185fe4333cecc02b9f2e0ced395253a2b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 12 Nov 2020 18:28:44 +0200 Subject: [PATCH 002/111] Add formatter on the buckets labels --- .../vis_type_pie/public/pie_component.tsx | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 1d549b49af2cbe..e179695ce756ad 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -70,6 +70,12 @@ export interface PieComponentProps { } export type PieComponentType = typeof PieComponent; +interface BucketColumns extends DatatableColumn { + format?: { + id?: string; + params?: { pattern?: string; [key: string]: any }; + }; +} const EMPTY_SLICE = Symbol('empty_slice'); @@ -82,12 +88,14 @@ const PieComponent = (props: PieComponentProps) => { const chartBaseTheme = getThemeService().useChartsBaseTheme(); const defaultPalette = getColorsService().getAll()[0]; - const [showLegend, setShowLegend] = useState(() => { - // TODO: Check when this bwc can safely be removed - const bwcLegendStateDefault = - props.visParams.addLegend == null ? true : props.visParams.addLegend; - return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; - }); + // const [showLegend, setShowLegend] = useState(() => { + // // TODO: Check when this bwc can safely be removed + // const bwcLegendStateDefault = + // props.visParams.addLegend == null ? true : props.visParams.addLegend; + // return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; + // }); + + const [showLegend, setShowLegend] = useState(true); const fillLabel: Partial = { textInvertible: true, @@ -239,6 +247,10 @@ const PieComponent = (props: PieComponentProps) => { circlePadding: 4, emptySizeRatio: visParams.isDonut ? 0.3 : 0, }; + if (!visParams.labels.show) { + // Force all labels to be linked, then prevent links from showing + config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; + } const metricColumn = visData.columns[visParams.dimensions.metric.accessor]; const metricFieldFormatter = getFormatService().deserialize(visParams.dimensions.metric.format); @@ -249,10 +261,10 @@ const PieComponent = (props: PieComponentProps) => { }, }); - const bucketColumns: DatatableColumn[] = []; + const bucketColumns: BucketColumns[] = []; if (visParams.dimensions.buckets) { visParams.dimensions.buckets.forEach((b) => { - bucketColumns.push(visData.columns[b.accessor]); + bucketColumns.push({ ...visData.columns[b.accessor], format: b.format }); }); } else { bucketColumns.push(visData.columns[0]); @@ -269,12 +281,9 @@ const PieComponent = (props: PieComponentProps) => { groupByRollup: (d: Datum) => d[col.id] ?? EMPTY_SLICE, showAccessor: (d: Datum) => d !== EMPTY_SLICE, nodeLabel: (d: unknown) => { - if (!visParams.labels.show || d === EMPTY_SLICE) { - return ''; + if (col.meta.params) { + return getFormatService().deserialize(col.format).convert(d) ?? ''; } - // if (col.meta.params) { - // return getFormatService().deserialize(col.format).convert(d) ?? ''; - // } return String(d); }, fillLabel, @@ -317,7 +326,7 @@ const PieComponent = (props: PieComponentProps) => { { // const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); @@ -332,9 +341,11 @@ const PieComponent = (props: PieComponentProps) => { data={visData.rows} valueAccessor={(d: Datum) => getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} - valueGetter={!visParams.labels.show ? undefined : 'percent'} + valueGetter={!visParams.labels.show || !visParams.labels.values ? undefined : 'percent'} valueFormatter={(d: number) => - !visParams.labels.show ? '' : metricFieldFormatter.convert(d) + !visParams.labels.show || !visParams.labels.values + ? '' + : metricFieldFormatter.convert(d) } layers={layers} config={config} From a8b20f322d4693372862480a952dfff192f7d244 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 16 Nov 2020 13:46:31 +0200 Subject: [PATCH 003/111] Config the new plugin, toggle tooltip --- .github/CODEOWNERS | 1 + .i18nrc.json | 1 + docs/developer/plugin-list.asciidoc | 4 + packages/kbn-optimizer/limits.yml | 1 + src/plugins/vis_type_pie/public/index.ts | 2 + .../vis_type_pie/public/pie_component.tsx | 7 ++ src/plugins/vis_type_pie/public/plugin.ts | 4 +- .../vis_type_pie/public/utils/index.ts | 20 +++++ .../public/utils/truncate_labels.ts | 25 +++++++ .../vis_type_pie/public/vis_type/index.ts | 4 +- src/plugins/vis_type_vislib/kibana.json | 2 +- src/plugins/vis_type_vislib/public/pie.ts | 75 +------------------ 12 files changed, 71 insertions(+), 75 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/utils/index.ts create mode 100644 src/plugins/vis_type_pie/public/utils/truncate_labels.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b7fb3ff04db710..097475703e9623 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -25,6 +25,7 @@ /src/plugins/vis_type_vega/ @elastic/kibana-app /src/plugins/vis_type_vislib/ @elastic/kibana-app /src/plugins/vis_type_xy/ @elastic/kibana-app +/src/plugins/vis_type_pie/ @elastic/kibana-app /src/plugins/visualize/ @elastic/kibana-app /src/plugins/visualizations/ @elastic/kibana-app diff --git a/.i18nrc.json b/.i18nrc.json index 653c67b535bff7..8d64944f4a49fc 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -58,6 +58,7 @@ "visTypeVega": "src/plugins/vis_type_vega", "visTypeVislib": "src/plugins/vis_type_vislib", "visTypeXy": "src/plugins/vis_type_xy", + "visTypePie": "src/plugins/vis_type_pie", "visualizations": "src/plugins/visualizations", "lensOss": "src/plugins/lens_oss", "mapsOss": "src/plugins/maps_oss", diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index e89b6d86361c7f..0e8a1c969676f6 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -241,6 +241,10 @@ The plugin exposes the static DefaultEditorController class to consume. |Contains the metric visualization. +|{kib-repo}blob/{branch}/src/plugins/vis_type_pie/README.md[visTypePie] +|Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Charts Library advanced setting. + + |{kib-repo}blob/{branch}/src/plugins/vis_type_table/README.md[visTypeTable] |Contains the data table visualization, that allows presenting data in a simple table format. diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index e326c8e2cac39e..d6c6a35bfc9a66 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -103,3 +103,4 @@ pageLoadAssetSize: visualize: 57431 watcher: 43598 stackAlerts: 29684 + visTypePie: 34051 diff --git a/src/plugins/vis_type_pie/public/index.ts b/src/plugins/vis_type_pie/public/index.ts index 2ab0f0127e0687..91528f8ff339c2 100644 --- a/src/plugins/vis_type_pie/public/index.ts +++ b/src/plugins/vis_type_pie/public/index.ts @@ -18,4 +18,6 @@ */ import { VisTypePiePlugin } from './plugin'; +export { pieVisType } from './vis_type'; + export const plugin = () => new VisTypePiePlugin(); diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index e179695ce756ad..eb68656c859ee4 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -41,6 +41,8 @@ import { Settings, RenderChangeListener, ElementClickListener, + TooltipProps, + TooltipType, } from '@elastic/charts'; import { keys } from '@elastic/eui'; import { SeriesLayer } from '../../charts/public'; @@ -315,6 +317,10 @@ const PieComponent = (props: PieComponentProps) => { }; }); + const tooltip: TooltipProps = { + type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, + }; + return (
{/* { showLegend={showLegend} legendPosition={visParams.legendPosition || Position.Right} legendMaxDepth={undefined} + tooltip={tooltip} // onElementClick={(args) => { // const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index f29e677bcf12df..be69ced3f39661 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -23,7 +23,7 @@ import { ChartsPluginSetup } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; import { createPieVisFn } from './pie_fn'; import { pieVisRenderer } from './pie_renderer'; -import { pieVisTypeDefinition } from './vis_type'; +import { pieVisType } from './vis_type'; import { setThemeService, setColorsService, setFormatService } from './services'; export interface VisTypePieSetupDependencies { @@ -50,7 +50,7 @@ export class VisTypePiePlugin { [createPieVisFn].forEach(expressions.registerFunction); expressions.registerRenderer(pieVisRenderer); - visualizations.createBaseVisualization(pieVisTypeDefinition); + visualizations.createBaseVisualization(pieVisType(true)); // core.getStartServices().then(([coreStart]) => { // visualizations.registerAlias(getLensAliasConfig(coreStart.docLinks)); // }); diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts new file mode 100644 index 00000000000000..afa88f3a3ebee9 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { truncateLabels } from './truncate_labels'; diff --git a/src/plugins/vis_type_pie/public/utils/truncate_labels.ts b/src/plugins/vis_type_pie/public/utils/truncate_labels.ts new file mode 100644 index 00000000000000..a6b11230b4cf1a --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/truncate_labels.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const truncateLabels = (text: string, size: number | null): string => { + if (size === 0 || !size || size >= text.length) return text; + return text.substr(0, size) + '…'; +}; + +export { truncateLabels }; diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index c6692073377edf..8e7334bd9fbc0a 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -19,4 +19,6 @@ import { getPieVisTypeDefinition } from './pie'; -export const pieVisTypeDefinition = getPieVisTypeDefinition(true); +export const pieVisType = (showElasticChartsOptions?: boolean) => { + return getPieVisTypeDefinition(showElasticChartsOptions); +}; diff --git a/src/plugins/vis_type_vislib/kibana.json b/src/plugins/vis_type_vislib/kibana.json index 720abff16b7c77..61e9c53c982536 100644 --- a/src/plugins/vis_type_vislib/kibana.json +++ b/src/plugins/vis_type_vislib/kibana.json @@ -5,5 +5,5 @@ "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "kibanaLegacy"], "optionalPlugins": ["visTypeXy"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor"] + "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypePie"] } diff --git a/src/plugins/vis_type_vislib/public/pie.ts b/src/plugins/vis_type_vislib/public/pie.ts index 58f7dd0df89e86..94ac0444e77c13 100644 --- a/src/plugins/vis_type_vislib/public/pie.ts +++ b/src/plugins/vis_type_vislib/public/pie.ts @@ -17,14 +17,9 @@ * under the License. */ -import { i18n } from '@kbn/i18n'; - -import { AggGroupNames } from '../../data/public'; -import { Schemas } from '../../vis_default_editor/public'; -import { PieOptions } from './components/options'; -import { getPositions, Positions } from './utils/collections'; +import { pieVisType } from '../../vis_type_pie/public'; import { CommonVislibParams } from './types'; -import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions } from '../../../plugins/visualizations/public'; import { toExpressionAst } from './to_ast_pie'; export interface PieVisParams extends CommonVislibParams { @@ -39,69 +34,7 @@ export interface PieVisParams extends CommonVislibParams { } export const pieVisTypeDefinition: BaseVisTypeOptions = { - name: 'pie', - title: i18n.translate('visTypeVislib.pie.pieTitle', { defaultMessage: 'Pie' }), - icon: 'visPie', - description: i18n.translate('visTypeVislib.pie.pieDescription', { - defaultMessage: 'Compare parts of a whole', - }), - getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], + ...(pieVisType() as BaseVisTypeOptions), toExpressionAst, - visConfig: { - defaults: { - type: 'pie', - addTooltip: true, - addLegend: true, - legendPosition: Positions.RIGHT, - isDonut: true, - labels: { - show: false, - values: true, - last_level: true, - truncate: 100, - }, - }, - }, - editorConfig: { - collections: { - legendPositions: getPositions(), - }, - optionsTemplate: PieOptions, - schemas: new Schemas([ - { - group: AggGroupNames.Metrics, - name: 'metric', - title: i18n.translate('visTypeVislib.pie.metricTitle', { - defaultMessage: 'Slice size', - }), - min: 1, - max: 1, - aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], - defaults: [{ schema: 'metric', type: 'count' }], - }, - { - group: AggGroupNames.Buckets, - name: 'segment', - title: i18n.translate('visTypeVislib.pie.segmentTitle', { - defaultMessage: 'Split slices', - }), - min: 0, - max: Infinity, - aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], - }, - { - group: AggGroupNames.Buckets, - name: 'split', - title: i18n.translate('visTypeVislib.pie.splitTitle', { - defaultMessage: 'Split chart', - }), - mustBeFirst: true, - min: 0, - max: 1, - aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], - }, - ]), - }, - hierarchicalData: true, - responseHandler: 'vislib_slices', + visualization: undefined, }; From 5016150256269a2ff925e0ccd573d8b7351a7391 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 16 Nov 2020 15:39:18 +0200 Subject: [PATCH 004/111] Aff filtering on slice click --- src/plugins/vis_type_pie/public/chart.scss | 19 +++- .../vis_type_pie/public/pie_component.tsx | 95 ++++++++++++------- 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index 239ee8a60ec9f6..6dd6b29e511a14 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -1,6 +1,15 @@ +.pieChart__wrapper, .pieChart__container { - width: 100%; - height: 100%; - position: relative; - } - \ No newline at end of file + display: flex; + flex: 1 1 auto; + min-height: 0; + min-width: 0; +} + +.pieChart__container { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index eb68656c859ee4..08a73106375674 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -40,7 +40,6 @@ import { Position, Settings, RenderChangeListener, - ElementClickListener, TooltipProps, TooltipType, } from '@elastic/charts'; @@ -55,6 +54,7 @@ import { SeriesLayer } from '../../charts/public'; // ClickTriggerEvent, // } from '../../charts/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; +import { ValueClickContext } from '../../embeddable/public'; import { PieVisParams } from './types'; import { getThemeService, getColorsService, getFormatService } from './services'; @@ -115,11 +115,34 @@ const PieComponent = (props: PieComponentProps) => { [props] ); + // move it to utils const handleFilterClick = useCallback( - (visData: Datatable): ElementClickListener => (elements) => { - // console.log('boom'); + (clickedLayers: LayerValue[], bucketColumns: BucketColumns[], visData: Datatable): void => { + const data: ValueClickContext['data']['data'] = []; + const matchingIndex = visData.rows.findIndex((row) => + clickedLayers.every((layer, index) => { + const columnId = bucketColumns[index].id; + return row[columnId] === layer.groupByRollup; + }) + ); + + data.push( + ...clickedLayers.map((clickedLayer, index) => ({ + column: visData.columns.findIndex((col) => col.id === bucketColumns[index].id), + row: matchingIndex, + value: clickedLayer.groupByRollup, + table: visData, + })) + ); + + const event = { + name: 'filterBucket', + data: { data }, + }; + + props.fireEvent(event); }, - [] + [props] ); // const getFilterEventData = useCallback( @@ -323,42 +346,42 @@ const PieComponent = (props: PieComponentProps) => { return (
- {/* + {/* */} - - { - // const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); - - // onClickValue(desanitizeFilterContext(context)); - // }} - onElementClick={handleFilterClick(visData)} - theme={chartTheme} - baseTheme={chartBaseTheme} - /> - getSliceValue(d, metricColumn)} - percentFormatter={(d: number) => percentFormatter.convert(d / 100)} - valueGetter={!visParams.labels.show || !visParams.labels.values ? undefined : 'percent'} - valueFormatter={(d: number) => - !visParams.labels.show || !visParams.labels.values - ? '' - : metricFieldFormatter.convert(d) - } - layers={layers} - config={config} - topGroove={!visParams.labels.show ? 0 : undefined} - /> - + + { + handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); + }} + // onElementClick={handleFilterClick(visData)} + theme={chartTheme} + baseTheme={chartBaseTheme} + /> + getSliceValue(d, metricColumn)} + percentFormatter={(d: number) => percentFormatter.convert(d / 100)} + valueGetter={!visParams.labels.show || !visParams.labels.values ? undefined : 'percent'} + valueFormatter={(d: number) => + !visParams.labels.show || !visParams.labels.values + ? '' + : metricFieldFormatter.convert(d) + } + layers={layers} + config={config} + topGroove={!visParams.labels.show ? 0 : undefined} + /> + +
); }; From 0d9bb2e5dfaa2da973bec782d6e2379272b68617 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 16 Nov 2020 18:07:09 +0200 Subject: [PATCH 005/111] minor fixes --- .../vis_type_pie/public/pie_component.tsx | 28 ++++++++++--------- .../vis_type_pie/public/utils/index.ts | 20 ------------- .../public/utils/truncate_labels.ts | 25 ----------------- 3 files changed, 15 insertions(+), 58 deletions(-) delete mode 100644 src/plugins/vis_type_pie/public/utils/index.ts delete mode 100644 src/plugins/vis_type_pie/public/utils/truncate_labels.ts diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 08a73106375674..5fa6b7a586ac42 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -99,13 +99,6 @@ const PieComponent = (props: PieComponentProps) => { const [showLegend, setShowLegend] = useState(true); - const fillLabel: Partial = { - textInvertible: true, - valueFont: { - fontWeight: 700, - }, - }; - const onRenderChange = useCallback( (isRendered) => { if (isRendered) { @@ -254,6 +247,17 @@ const PieComponent = (props: PieComponentProps) => { return Number.EPSILON; } + const fillLabel: Partial = { + textInvertible: true, + valueFont: { + fontWeight: 700, + }, + }; + + if (!visParams.labels.values) { + fillLabel.valueFormatter = () => ''; + } + const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, @@ -263,9 +267,10 @@ const PieComponent = (props: PieComponentProps) => { minFontSize: 10, maxFontSize: 16, linkLabel: { - maxCount: 5, + maxCount: Number.POSITIVE_INFINITY, fontSize: 11, textColor: chartTheme.axes?.axisTitle?.fill, + maxTextLength: visParams.labels.truncate ?? undefined, }, sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill, sectorLineWidth: 1.5, @@ -361,7 +366,6 @@ const PieComponent = (props: PieComponentProps) => { onElementClick={(args) => { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); }} - // onElementClick={handleFilterClick(visData)} theme={chartTheme} baseTheme={chartBaseTheme} /> @@ -370,11 +374,9 @@ const PieComponent = (props: PieComponentProps) => { data={visData.rows} valueAccessor={(d: Datum) => getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} - valueGetter={!visParams.labels.show || !visParams.labels.values ? undefined : 'percent'} + valueGetter={!visParams.labels.show ? undefined : 'percent'} valueFormatter={(d: number) => - !visParams.labels.show || !visParams.labels.values - ? '' - : metricFieldFormatter.convert(d) + !visParams.labels.show ? '' : metricFieldFormatter.convert(d) } layers={layers} config={config} diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts deleted file mode 100644 index afa88f3a3ebee9..00000000000000 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export { truncateLabels } from './truncate_labels'; diff --git a/src/plugins/vis_type_pie/public/utils/truncate_labels.ts b/src/plugins/vis_type_pie/public/utils/truncate_labels.ts deleted file mode 100644 index a6b11230b4cf1a..00000000000000 --- a/src/plugins/vis_type_pie/public/utils/truncate_labels.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const truncateLabels = (text: string, size: number | null): string => { - if (size === 0 || !size || size >= text.length) return text; - return text.substr(0, size) + '…'; -}; - -export { truncateLabels }; From e916ea5422a68328f253c8bace73b4f4367dcfd7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 18 Nov 2020 13:27:49 +0200 Subject: [PATCH 006/111] fix eslint error --- .../vis_type_pie/public/components/index.ts | 20 +++ .../public/components/tooltip.scss | 34 ++++ .../public/components/tooltip.tsx | 150 ++++++++++++++++++ .../vis_type_pie/public/editor/collections.ts | 36 ++++- .../public/editor/components/pie.tsx | 33 +++- .../vis_type_pie/public/pie_component.tsx | 40 +++-- src/plugins/vis_type_pie/public/pie_fn.ts | 4 + .../vis_type_pie/public/pie_renderer.tsx | 3 +- .../vis_type_pie/public/types/params.ts | 22 ++- .../public/utils/build_hierarchical_data.ts | 113 +++++++++++++ .../vis_type_pie/public/utils/index.ts | 20 +++ .../public/utils/response_handler.js | 123 ++++++++++++++ .../vis_type_pie/public/vis_type/pie.ts | 12 +- 13 files changed, 576 insertions(+), 34 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/components/index.ts create mode 100644 src/plugins/vis_type_pie/public/components/tooltip.scss create mode 100644 src/plugins/vis_type_pie/public/components/tooltip.tsx create mode 100644 src/plugins/vis_type_pie/public/utils/build_hierarchical_data.ts create mode 100644 src/plugins/vis_type_pie/public/utils/index.ts create mode 100644 src/plugins/vis_type_pie/public/utils/response_handler.js diff --git a/src/plugins/vis_type_pie/public/components/index.ts b/src/plugins/vis_type_pie/public/components/index.ts new file mode 100644 index 00000000000000..fda1338ebb968f --- /dev/null +++ b/src/plugins/vis_type_pie/public/components/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { getTooltip } from './tooltip'; diff --git a/src/plugins/vis_type_pie/public/components/tooltip.scss b/src/plugins/vis_type_pie/public/components/tooltip.scss new file mode 100644 index 00000000000000..8b5e269c787cec --- /dev/null +++ b/src/plugins/vis_type_pie/public/components/tooltip.scss @@ -0,0 +1,34 @@ +.detailedTooltip { + @include euiToolTipStyle('s'); + pointer-events: none; + max-width: $euiSizeXL * 10; + overflow: hidden; + padding: $euiSizeS; + + table { + td, + th { + text-align: left; + padding: $euiSizeXS; + overflow-wrap: break-word; + word-wrap: break-word; + } + } + } + + .detailedTooltip__header { + > :last-child { + margin-bottom: $euiSizeS; + } + } + + .detailedTooltip__labelContainer, + .detailedTooltip__valueContainer { + overflow-wrap: break-word; + word-wrap: break-word; + } + + .detailedTooltip__label { + font-weight: $euiFontWeightMedium; + color: shade($euiColorGhost, 20%); + } \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/components/tooltip.tsx b/src/plugins/vis_type_pie/public/components/tooltip.tsx new file mode 100644 index 00000000000000..bbf860f0fb54ad --- /dev/null +++ b/src/plugins/vis_type_pie/public/components/tooltip.tsx @@ -0,0 +1,150 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { CustomTooltip, TooltipValue } from '@elastic/charts'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { Datatable, DatatableColumn } from '../../../expressions/public'; +import { IFieldFormat } from '../../../data/public'; +import { BucketColumns } from '../types'; +import { getFormatService } from '../services'; + +import './tooltip.scss'; + +interface TooltipData { + field: string; + bucket: string; + metric: string; +} + +const getTooltipData = ( + visData: Datatable, + metricFormatter: IFieldFormat, + value: TooltipValue, + columns: BucketColumns[], + metricColumn: DatatableColumn +): TooltipData[] => { + const data: TooltipData[] = []; + if (!value.valueAccessor) return []; + const bucketColumn = columns[(value.valueAccessor as number) - 1]; + + // inner circle + if (value.valueAccessor === 1) { + return [ + { + field: value.label, + bucket: columns[0].name, + metric: value.formattedValue, + }, + ]; + } + + const matchingRow = visData.rows.find((row) => { + const rowLabel = getFormatService() + .deserialize(bucketColumn.format) + .convert(row[bucketColumn.id]); + return rowLabel === value.label && row[metricColumn.id] === value.value; + }); + + const slice = []; + for (let i = 0; i < value.valueAccessor; i++) { + const columnId = columns[i].id; + const matchingIndex = visData.columns.findIndex((col) => col.id === columnId); + const bucketColumnValue = visData.columns[matchingIndex + 1]; + + const metricValue = metricFormatter.convert(matchingRow?.[bucketColumnValue.id]); + slice.push(metricValue); + + data.push({ + field: columns[i].name, + bucket: getFormatService().deserialize(columns[i].format).convert(matchingRow?.[columnId]), + metric: metricValue, + }); + } + return data; +}; + +const renderData = ({ field, bucket, metric }: TooltipData, index: number) => + field && bucket ? ( + + +
+ + {field} +
+ + +
{bucket}
+ + {metric} + + ) : null; + +export const getTooltip = ( + data: Datatable, + metricFormatter: IFieldFormat, + bucketColumns: BucketColumns[], + metricColumn: DatatableColumn +): CustomTooltip => { + return function DetailedTooltip({ values }) { + const highlightedValue = values[0]; + + if (!highlightedValue) { + return null; + } + + const tooltipData = getTooltipData( + data, + metricFormatter, + highlightedValue, + bucketColumns, + metricColumn + ); + + if (tooltipData.length === 0) { + return null; + } + + return ( + +
+ + + + + + + + + + {tooltipData.map(renderData)} +
{/* {metricCol.label} */}
+
+
+ ); + }; +}; diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts index 40c854a502ac92..3a740eff42b931 100644 --- a/src/plugins/vis_type_pie/public/editor/collections.ts +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -19,8 +19,9 @@ import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; +import { LabelPositions, ValueFormats } from '../types'; -export const getPositions = () => [ +export const getLegendPositions = () => [ { text: i18n.translate('visTypePie.legendPositions.topText', { defaultMessage: 'Top', @@ -47,7 +48,32 @@ export const getPositions = () => [ }, ]; -export const getConfigCollections = () => ({ - legendPositions: getPositions(), - positions: getPositions(), -}); +export const getLabelPositions = () => [ + { + text: i18n.translate('visTypePie.labelPositions.insideText', { + defaultMessage: 'Inside', + }), + value: LabelPositions.INSIDE, + }, + { + text: i18n.translate('visTypePie.labelPositions.insideOrOutsideText', { + defaultMessage: 'Inside or outside', + }), + value: LabelPositions.DEFAULT, + }, +]; + +export const getValuesFormats = () => [ + { + text: i18n.translate('visTypePie.valuesFormats.percent', { + defaultMessage: 'Show Percent', + }), + value: ValueFormats.PERCENT, + }, + { + text: i18n.translate('visTypePie.valuesFormats.value', { + defaultMessage: 'Show value', + }), + value: ValueFormats.VALUE, + }, +]; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index b893b4913ee461..345c9adc9e80a0 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -24,8 +24,9 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; -import { BasicOptions, SwitchOption } from '../../../../charts/public'; +import { BasicOptions, SwitchOption, SelectOption } from '../../../../charts/public'; import { PieVisParams } from '../../types'; +import { getLabelPositions, getValuesFormats } from '../collections'; function PieOptions(props: VisOptionsProps) { const { stateParams, setValue } = props; @@ -55,6 +56,14 @@ function PieOptions(props: VisOptionsProps) { setValue={setValue} /> + @@ -77,12 +86,14 @@ function PieOptions(props: VisOptionsProps) { value={stateParams.labels.show} setValue={setLabels} /> - ) { value={stateParams.labels.values} setValue={setLabels} /> + diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 5fa6b7a586ac42..2239f015b8f69f 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -56,8 +56,9 @@ import { SeriesLayer } from '../../charts/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { ValueClickContext } from '../../embeddable/public'; -import { PieVisParams } from './types'; +import { PieVisParams, BucketColumns, LabelPositions, ValueFormats } from './types'; import { getThemeService, getColorsService, getFormatService } from './services'; +import { getTooltip } from './components'; // import { colorSchemas } from 'src/plugins/charts/public'; // import { ChartType } from '../common'; @@ -67,17 +68,12 @@ export interface PieComponentProps { visParams: PieVisParams; visData: Datatable; uiState: IInterpreterRenderHandlers['uiState']; + visFormattedData: any; fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; } export type PieComponentType = typeof PieComponent; -interface BucketColumns extends DatatableColumn { - format?: { - id?: string; - params?: { pattern?: string; [key: string]: any }; - }; -} const EMPTY_SLICE = Symbol('empty_slice'); @@ -199,10 +195,7 @@ const PieComponent = (props: PieComponentProps) => { [props.uiState?.emit, props.uiState?.get, props.uiState?.set, props.uiState?.setSilent] ); - const { visData, visParams } = props; - - // console.dir(visData); - // console.dir(visParams); + const { visData, visParams, visFormattedData } = props; // const config = getConfig(visData, visParams); // const legendPosition = useMemo(() => config.legend.position ?? Position.Right, [ @@ -281,8 +274,9 @@ const PieComponent = (props: PieComponentProps) => { // Force all labels to be linked, then prevent links from showing config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; } - - const metricColumn = visData.columns[visParams.dimensions.metric.accessor]; + if (visParams.labels.position === LabelPositions.INSIDE) { + config.linkLabel = { maxCount: 0 }; + } const metricFieldFormatter = getFormatService().deserialize(visParams.dimensions.metric.format); const percentFormatter = getFormatService().deserialize({ id: 'percent', @@ -299,6 +293,10 @@ const PieComponent = (props: PieComponentProps) => { } else { bucketColumns.push(visData.columns[0]); } + // calclulate metric column --> move to utils + const lastBucketId = bucketColumns[bucketColumns.length - 1].id; + const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); + const metricColumn = visData.columns[matchingIndex + 1]; const totalSeriesCount = uniq( visData.rows.map((row) => { @@ -334,7 +332,7 @@ const PieComponent = (props: PieComponentProps) => { } const outputColor = defaultPalette.getColor(seriesLayers, { - behindText: true, + behindText: visParams.labels.show, maxDepth: visData.columns.length, totalSeries: totalSeriesCount, }); @@ -347,6 +345,12 @@ const PieComponent = (props: PieComponentProps) => { const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, + // customTooltip: getTooltip( + // visData, + // metricFieldFormatter, + // bucketColumns, + // metricColumn + // ), }; return ( @@ -361,7 +365,7 @@ const PieComponent = (props: PieComponentProps) => { { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); @@ -374,7 +378,11 @@ const PieComponent = (props: PieComponentProps) => { data={visData.rows} valueAccessor={(d: Datum) => getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} - valueGetter={!visParams.labels.show ? undefined : 'percent'} + valueGetter={ + !visParams.labels.show || visParams.labels.valuesFormat === ValueFormats.VALUE + ? undefined + : 'percent' + } valueFormatter={(d: number) => !visParams.labels.show ? '' : metricFieldFormatter.convert(d) } diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 6123a2e7d32463..604f7e7ea9b0ce 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; import { PieVisParams } from './types'; +import { vislibSlicesResponseHandler } from './utils'; export const vislibPieName = 'pie_vis'; @@ -30,6 +31,7 @@ interface Arguments { export interface RenderValue { visData: Datatable; visType: string; + visFormattedData: any; visConfig: PieVisParams; } @@ -56,12 +58,14 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ }, fn(context, args) { const visConfig = JSON.parse(args.visConfig) as PieVisParams; + const visFormattedData = vislibSlicesResponseHandler(context, visConfig.dimensions); return { type: 'render', as: vislibPieName, value: { visData: context, + visFormattedData, visConfig, visType: 'pie', params: { diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index baaec8902c5b29..f7690c61796d5f 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -39,7 +39,7 @@ export const pieVisRenderer: ExpressionRenderDefinition = { name: vislibPieName, displayName: 'Pie visualization', reuseDomNode: true, - render: (domNode, { visConfig, visData }, handlers) => { + render: (domNode, { visConfig, visData, visFormattedData }, handlers) => { const showNoResult = shouldShowNoResultsMessage(visData); const isSplitChart = Boolean(visConfig.dimensions.splitRow); @@ -51,6 +51,7 @@ export const pieVisRenderer: ExpressionRenderDefinition = { ; + }; +} + +export interface Dimensions { + metric: Dimension; + buckets?: Dimension[]; + splitRow?: Dimension[]; + splitColumn?: Dimension[]; +} + +interface Slice { + name: string; + size: number; + parent?: Slice; + children?: []; + rawData?: { + table: Table; + row: number; + column: number; + value: string | number | object; + }; +} + +export const buildHierarchicalData = (table: Table, { metric, buckets = [] }: Dimensions) => { + let slices: Slice[]; + const names: { [key: string]: string } = {}; + const metricColumn = table.columns[metric.accessor]; + const metricFieldFormatter = metric.format; + + if (!buckets.length) { + slices = [ + { + name: metricColumn.name, + size: table.rows[0][metricColumn.id] as number, + }, + ]; + names[metricColumn.name] = metricColumn.name; + } else { + slices = []; + table.rows.forEach((row, rowIndex) => { + let parent: Slice; + let dataLevel = slices; + + buckets.forEach((bucket) => { + const bucketColumn = table.columns[bucket.accessor]; + const bucketValueColumn = table.columns[bucket.accessor + 1]; + const bucketFormatter = getFormatService().deserialize(bucket.format); + const name = bucketFormatter.convert(row[bucketColumn.id]); + const size = row[bucketValueColumn.id] as number; + names[name] = name; + + let slice = dataLevel.find((dataLevelSlice) => dataLevelSlice.name === name); + if (!slice) { + slice = { + name, + size, + parent, + children: [], + rawData: { + table, + row: rowIndex, + column: bucket.accessor, + value: row[bucketColumn.id], + }, + }; + dataLevel.push(slice); + } + + parent = slice; + dataLevel = slice.children as []; + }); + }); + } + + return { + hits: table.rows.length, + raw: table, + names: toArray(names), + tooltipFormatter: metricFieldFormatter, + slices: { + children: [...slices], + }, + }; +}; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts new file mode 100644 index 00000000000000..8929f5d9f39dd4 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { vislibSlicesResponseHandler } from './response_handler'; diff --git a/src/plugins/vis_type_pie/public/utils/response_handler.js b/src/plugins/vis_type_pie/public/utils/response_handler.js new file mode 100644 index 00000000000000..d3dee8612dc971 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/response_handler.js @@ -0,0 +1,123 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getFormatService } from '../services'; +import { buildHierarchicalData } from './build_hierarchical_data'; + +function tableResponseHandler(table, dimensions) { + const converted = { tables: [] }; + const split = dimensions.splitColumn || dimensions.splitRow; + + if (split) { + converted.direction = dimensions.splitRow ? 'row' : 'column'; + const splitColumnIndex = split[0].accessor; + const splitColumnFormatter = getFormatService().deserialize(split[0].format); + const splitColumn = table.columns[splitColumnIndex]; + const splitMap = {}; + let splitIndex = 0; + + table.rows.forEach((row, rowIndex) => { + const splitValue = row[splitColumn.id]; + + if (!splitMap.hasOwnProperty(splitValue)) { + splitMap[splitValue] = splitIndex++; + const tableGroup = { + $parent: converted, + title: `${splitColumnFormatter.convert(splitValue)}: ${splitColumn.name}`, + name: splitColumn.name, + key: splitValue, + column: splitColumnIndex, + row: rowIndex, + table, + tables: [], + }; + tableGroup.tables.push({ + $parent: tableGroup, + columns: table.columns, + rows: [], + }); + + converted.tables.push(tableGroup); + } + + const tableIndex = splitMap[splitValue]; + converted.tables[tableIndex].tables[0].rows.push(row); + }); + } else { + converted.tables.push({ + columns: table.columns, + rows: table.rows, + }); + } + + return converted; +} + +function convertTableGroup(tableGroup, convertTable) { + const tables = tableGroup.tables; + + if (!tables || !tables.length) return; + + const firstChild = tables[0]; + if (firstChild.columns) { + const chart = convertTable(firstChild); + // if chart is within a split, assign group title to its label + if (tableGroup.$parent) { + chart.label = tableGroup.title; + } + return chart; + } + + const out = {}; + let outList; + + tables.forEach(function (table) { + if (!outList) { + const direction = tableGroup.direction === 'row' ? 'rows' : 'columns'; + outList = out[direction] = []; + } + + let output; + if ((output = convertTableGroup(table, convertTable))) { + outList.push(output); + } + }); + + return out; +} + +function handlerFunction(convertTable) { + return function (response, dimensions) { + const tableGroup = tableResponseHandler(response, dimensions); + let converted = convertTableGroup(tableGroup, (table) => { + return convertTable(table, dimensions); + }); + if (!converted) { + // mimic a row of tables that doesn't have any tables + // https://github.com/elastic/kibana/blob/7bfb68cd24ed42b1b257682f93c50cd8d73e2520/src/kibana/components/vislib/components/zero_injection/inject_zeros.js#L32 + converted = { rows: [] }; + } + + converted.hits = response.rows.length; + + return converted; + }; +} + +export const vislibSlicesResponseHandler = handlerFunction(buildHierarchicalData); diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 9df2030419e3aa..749bc8f65edf9b 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -26,9 +26,9 @@ import { Schemas } from '../../../vis_default_editor/public'; import { AggGroupNames } from '../../../data/public'; import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualizations/public'; -import { PieVisParams } from '../types'; +import { PieVisParams, LabelPositions, ValueFormats } from '../types'; import { toExpressionAst } from '../to_ast'; -import { getPositions, PieOptions } from '../editor'; +import { getLegendPositions, PieOptions } from '../editor'; export const getPieVisTypeDefinition = ( showElasticChartsOptions = false @@ -47,18 +47,20 @@ export const getPieVisTypeDefinition = ( addTooltip: true, addLegend: true, legendPosition: Position.Right, + nestedLegend: false, isDonut: true, labels: { - show: false, + show: true, values: true, - last_level: true, + valuesFormat: ValueFormats.PERCENT, truncate: 100, + position: LabelPositions.DEFAULT, }, }, }, editorConfig: { collections: { - legendPositions: getPositions(), + legendPositions: getLegendPositions(), }, optionsTemplate: PieOptions, schemas: new Schemas([ From bcbfd69b5bce15e750ae2e65c7eca3f3656169ef Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 18 Nov 2020 17:59:07 +0200 Subject: [PATCH 007/111] use legacy palette for now --- src/plugins/vis_type_pie/public/pie_component.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 2239f015b8f69f..bb4457cfd492ce 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -84,7 +84,7 @@ const PieComponent = (props: PieComponentProps) => { // const allSeries: Array = []; const chartTheme = getThemeService().useChartsTheme(); const chartBaseTheme = getThemeService().useChartsBaseTheme(); - const defaultPalette = getColorsService().getAll()[0]; + const defaultPalette = getColorsService().get('kibana_palette'); // const [showLegend, setShowLegend] = useState(() => { // // TODO: Check when this bwc can safely be removed @@ -260,7 +260,7 @@ const PieComponent = (props: PieComponentProps) => { minFontSize: 10, maxFontSize: 16, linkLabel: { - maxCount: Number.POSITIVE_INFINITY, + maxCount: 5, fontSize: 11, textColor: chartTheme.axes?.axisTitle?.fill, maxTextLength: visParams.labels.truncate ?? undefined, @@ -298,12 +298,6 @@ const PieComponent = (props: PieComponentProps) => { const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); const metricColumn = visData.columns[matchingIndex + 1]; - const totalSeriesCount = uniq( - visData.rows.map((row) => { - return bucketColumns.map(({ id: columnId }) => row[columnId]).join(','); - }) - ).length; - const layers: PartitionLayer[] = bucketColumns.map((col) => { return { groupByRollup: (d: Datum) => d[col.id] ?? EMPTY_SLICE, @@ -333,8 +327,8 @@ const PieComponent = (props: PieComponentProps) => { const outputColor = defaultPalette.getColor(seriesLayers, { behindText: visParams.labels.show, - maxDepth: visData.columns.length, - totalSeries: totalSeriesCount, + maxDepth: bucketColumns.length, + totalSeries: visData.rows.length, }); return outputColor || 'rgba(0,0,0,0)'; @@ -372,6 +366,7 @@ const PieComponent = (props: PieComponentProps) => { }} theme={chartTheme} baseTheme={chartBaseTheme} + onRenderChange={onRenderChange} /> Date: Thu, 19 Nov 2020 15:20:08 +0200 Subject: [PATCH 008/111] Add color picker to legend colors --- .../public/services/palettes/palettes.tsx | 8 +- .../public/components/tooltip.scss | 34 ---- .../public/components/tooltip.tsx | 150 ------------------ .../vis_type_pie/public/pie_component.tsx | 120 +++----------- src/plugins/vis_type_pie/public/pie_fn.ts | 4 - .../vis_type_pie/public/pie_renderer.tsx | 3 +- .../public/temp/color_picker.scss | 18 +++ .../vis_type_pie/public/temp/color_picker.tsx | 140 ++++++++++++++++ .../public/{components => temp}/index.ts | 2 +- .../vis_type_pie/public/types/params.ts | 4 + .../public/utils/build_hierarchical_data.ts | 113 ------------- .../public/utils/get_color_picker.tsx | 69 ++++++++ .../vis_type_pie/public/utils/get_layers.ts | 95 +++++++++++ .../vis_type_pie/public/utils/index.ts | 3 +- .../public/utils/response_handler.js | 123 -------------- 15 files changed, 357 insertions(+), 529 deletions(-) delete mode 100644 src/plugins/vis_type_pie/public/components/tooltip.scss delete mode 100644 src/plugins/vis_type_pie/public/components/tooltip.tsx create mode 100644 src/plugins/vis_type_pie/public/temp/color_picker.scss create mode 100644 src/plugins/vis_type_pie/public/temp/color_picker.tsx rename src/plugins/vis_type_pie/public/{components => temp}/index.ts (94%) delete mode 100644 src/plugins/vis_type_pie/public/utils/build_hierarchical_data.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_color_picker.tsx create mode 100644 src/plugins/vis_type_pie/public/utils/get_layers.ts delete mode 100644 src/plugins/vis_type_pie/public/utils/response_handler.js diff --git a/src/plugins/charts/public/services/palettes/palettes.tsx b/src/plugins/charts/public/services/palettes/palettes.tsx index c1fd7c3cc739fd..69f951fa6caa4f 100644 --- a/src/plugins/charts/public/services/palettes/palettes.tsx +++ b/src/plugins/charts/public/services/palettes/palettes.tsx @@ -115,9 +115,13 @@ function buildGradient( function buildSyncedKibanaPalette( colors: ChartsPluginSetup['legacyColors'] ): Omit { - function getColor(series: SeriesLayer[], chartConfiguration: ChartColorConfiguration = {}) { + function getColor( + series: SeriesLayer[], + chartConfiguration: ChartColorConfiguration = {}, + state?: unknown + ) { colors.mappedColors.mapKeys([series[0].name]); - const outputColor = colors.mappedColors.get(series[0].name); + const outputColor = state ?? colors.mappedColors.get(series[0].name); if (!chartConfiguration.maxDepth || chartConfiguration.maxDepth === 1) { return outputColor; diff --git a/src/plugins/vis_type_pie/public/components/tooltip.scss b/src/plugins/vis_type_pie/public/components/tooltip.scss deleted file mode 100644 index 8b5e269c787cec..00000000000000 --- a/src/plugins/vis_type_pie/public/components/tooltip.scss +++ /dev/null @@ -1,34 +0,0 @@ -.detailedTooltip { - @include euiToolTipStyle('s'); - pointer-events: none; - max-width: $euiSizeXL * 10; - overflow: hidden; - padding: $euiSizeS; - - table { - td, - th { - text-align: left; - padding: $euiSizeXS; - overflow-wrap: break-word; - word-wrap: break-word; - } - } - } - - .detailedTooltip__header { - > :last-child { - margin-bottom: $euiSizeS; - } - } - - .detailedTooltip__labelContainer, - .detailedTooltip__valueContainer { - overflow-wrap: break-word; - word-wrap: break-word; - } - - .detailedTooltip__label { - font-weight: $euiFontWeightMedium; - color: shade($euiColorGhost, 20%); - } \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/components/tooltip.tsx b/src/plugins/vis_type_pie/public/components/tooltip.tsx deleted file mode 100644 index bbf860f0fb54ad..00000000000000 --- a/src/plugins/vis_type_pie/public/components/tooltip.tsx +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { CustomTooltip, TooltipValue } from '@elastic/charts'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; -import { Datatable, DatatableColumn } from '../../../expressions/public'; -import { IFieldFormat } from '../../../data/public'; -import { BucketColumns } from '../types'; -import { getFormatService } from '../services'; - -import './tooltip.scss'; - -interface TooltipData { - field: string; - bucket: string; - metric: string; -} - -const getTooltipData = ( - visData: Datatable, - metricFormatter: IFieldFormat, - value: TooltipValue, - columns: BucketColumns[], - metricColumn: DatatableColumn -): TooltipData[] => { - const data: TooltipData[] = []; - if (!value.valueAccessor) return []; - const bucketColumn = columns[(value.valueAccessor as number) - 1]; - - // inner circle - if (value.valueAccessor === 1) { - return [ - { - field: value.label, - bucket: columns[0].name, - metric: value.formattedValue, - }, - ]; - } - - const matchingRow = visData.rows.find((row) => { - const rowLabel = getFormatService() - .deserialize(bucketColumn.format) - .convert(row[bucketColumn.id]); - return rowLabel === value.label && row[metricColumn.id] === value.value; - }); - - const slice = []; - for (let i = 0; i < value.valueAccessor; i++) { - const columnId = columns[i].id; - const matchingIndex = visData.columns.findIndex((col) => col.id === columnId); - const bucketColumnValue = visData.columns[matchingIndex + 1]; - - const metricValue = metricFormatter.convert(matchingRow?.[bucketColumnValue.id]); - slice.push(metricValue); - - data.push({ - field: columns[i].name, - bucket: getFormatService().deserialize(columns[i].format).convert(matchingRow?.[columnId]), - metric: metricValue, - }); - } - return data; -}; - -const renderData = ({ field, bucket, metric }: TooltipData, index: number) => - field && bucket ? ( - - -
- - {field} -
- - -
{bucket}
- - {metric} - - ) : null; - -export const getTooltip = ( - data: Datatable, - metricFormatter: IFieldFormat, - bucketColumns: BucketColumns[], - metricColumn: DatatableColumn -): CustomTooltip => { - return function DetailedTooltip({ values }) { - const highlightedValue = values[0]; - - if (!highlightedValue) { - return null; - } - - const tooltipData = getTooltipData( - data, - metricFormatter, - highlightedValue, - bucketColumns, - metricColumn - ); - - if (tooltipData.length === 0) { - return null; - } - - return ( - -
- - - - - - - - - - {tooltipData.map(renderData)} -
{/* {metricCol.label} */}
-
-
- ); - }; -}; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index bb4457cfd492ce..53b905740bbef6 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -25,7 +25,6 @@ import React, { useMemo, useState, } from 'react'; -import { uniq } from 'lodash'; import { Chart, @@ -33,7 +32,6 @@ import { LayerValue, Partition, PartitionConfig, - PartitionLayer, PartitionLayout, PartitionFillLabel, RecursivePartial, @@ -44,21 +42,19 @@ import { TooltipType, } from '@elastic/charts'; import { keys } from '@elastic/eui'; -import { SeriesLayer } from '../../charts/public'; // import { // getFilterFromChartClickEventFn, // getFilterFromSeriesFn, // LegendToggle, -// getBrushFromChartBrushEventFn, // ClickTriggerEvent, // } from '../../charts/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { ValueClickContext } from '../../embeddable/public'; import { PieVisParams, BucketColumns, LabelPositions, ValueFormats } from './types'; -import { getThemeService, getColorsService, getFormatService } from './services'; -import { getTooltip } from './components'; +import { getThemeService, getFormatService } from './services'; +import { getColorPicker, getLayers } from './utils'; // import { colorSchemas } from 'src/plugins/charts/public'; // import { ChartType } from '../common'; @@ -68,15 +64,12 @@ export interface PieComponentProps { visParams: PieVisParams; visData: Datatable; uiState: IInterpreterRenderHandlers['uiState']; - visFormattedData: any; fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; } export type PieComponentType = typeof PieComponent; -const EMPTY_SLICE = Symbol('empty_slice'); - const PieComponent = (props: PieComponentProps) => { /** * Stores all series labels to replicate vislib color map lookup @@ -84,7 +77,6 @@ const PieComponent = (props: PieComponentProps) => { // const allSeries: Array = []; const chartTheme = getThemeService().useChartsTheme(); const chartBaseTheme = getThemeService().useChartsBaseTheme(); - const defaultPalette = getColorsService().get('kibana_palette'); // const [showLegend, setShowLegend] = useState(() => { // // TODO: Check when this bwc can safely be removed @@ -92,8 +84,8 @@ const PieComponent = (props: PieComponentProps) => { // props.visParams.addLegend == null ? true : props.visParams.addLegend; // return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; // }); - const [showLegend, setShowLegend] = useState(true); + const [overwriteColors, setOverwriteColors] = useState(props.uiState?.get('vis.colors', {})); const onRenderChange = useCallback( (isRendered) => { @@ -191,47 +183,12 @@ const PieComponent = (props: PieComponentProps) => { props.uiState?.setSilent('vis.colors', null); props.uiState?.set('vis.colors', colors); props.uiState?.emit('colorChanged'); + setOverwriteColors(colors); }, [props.uiState?.emit, props.uiState?.get, props.uiState?.set, props.uiState?.setSilent] ); - const { visData, visParams, visFormattedData } = props; - - // const config = getConfig(visData, visParams); - // const legendPosition = useMemo(() => config.legend.position ?? Position.Right, [ - // config.legend.position, - // ]); - // const timeZone = getTimeZone(); - // const xDomain = - // config.xAxis.scale.type === ScaleType.Ordinal ? undefined : getXDomain(config.aspects.x.params); - // const hasBars = visParams.seriesParams.some( - // ({ type, data: { id: paramId } }) => - // type === ChartType.Histogram && config.aspects.y.find(({ aggId }) => aggId === paramId) - // ); - // const adjustedXDomain = - // config.xAxis.scale.type === ScaleType.Ordinal - // ? undefined - // : getAdjustedDomain(visData.rows, config.aspects.x, timeZone, xDomain, hasBars); - // const legendPosition = useMemo(() => config.legend.position ?? Position.Right, [ - // config.legend.position, - // ]); - // const isDarkMode = getThemeService().useDarkMode(); - // const getSeriesName = getSeriesNameFn(config.aspects, config.aspects.y.length > 1); - - // const getSeriesColor = useCallback( - // (series: XYChartSeriesIdentifier) => { - // const seriesName = getSeriesName(series); - // if (!seriesName) { - // return; - // } - - // const overwriteColors: Record = props.uiState?.get('vis.colors', {}); - - // allSeries.push(seriesName); - // return getColorsService().createColorLookupFunction(allSeries, overwriteColors)(seriesName); - // }, - // [allSeries, getSeriesName, props.uiState?.get] - // ); + const { visData, visParams } = props; function getSliceValue(d: Datum, metricColumn: DatatableColumn) { if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { @@ -285,68 +242,32 @@ const PieComponent = (props: PieComponentProps) => { }, }); + let layersColumns: Array> = []; const bucketColumns: BucketColumns[] = []; + let metricColumn: DatatableColumn; if (visParams.dimensions.buckets) { visParams.dimensions.buckets.forEach((b) => { bucketColumns.push({ ...visData.columns[b.accessor], format: b.format }); + layersColumns = [...bucketColumns]; }); + const lastBucketId = layersColumns[layersColumns.length - 1].id; + const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); + metricColumn = visData.columns[matchingIndex + 1]; } else { - bucketColumns.push(visData.columns[0]); + metricColumn = visData.columns[0]; + layersColumns.push({ + name: metricColumn.name, + }); } - // calclulate metric column --> move to utils - const lastBucketId = bucketColumns[bucketColumns.length - 1].id; - const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); - const metricColumn = visData.columns[matchingIndex + 1]; - - const layers: PartitionLayer[] = bucketColumns.map((col) => { - return { - groupByRollup: (d: Datum) => d[col.id] ?? EMPTY_SLICE, - showAccessor: (d: Datum) => d !== EMPTY_SLICE, - nodeLabel: (d: unknown) => { - if (col.meta.params) { - return getFormatService().deserialize(col.format).convert(d) ?? ''; - } - return String(d); - }, - fillLabel, - shape: { - fillColor: (d) => { - const seriesLayers: SeriesLayer[] = []; - - // Color is determined by round-robin on the index of the innermost slice - // This has to be done recursively until we get to the slice index - let tempParent: typeof d | typeof d['parent'] = d; - while (tempParent.parent && tempParent.depth > 0) { - seriesLayers.unshift({ - name: String(tempParent.parent.children[tempParent.sortIndex][0]), - rankAtDepth: tempParent.sortIndex, - totalSeriesAtDepth: tempParent.parent.children.length, - }); - tempParent = tempParent.parent; - } - - const outputColor = defaultPalette.getColor(seriesLayers, { - behindText: visParams.labels.show, - maxDepth: bucketColumns.length, - totalSeries: visData.rows.length, - }); - - return outputColor || 'rgba(0,0,0,0)'; - }, - }, - }; - }); + + const layers = getLayers(layersColumns, visParams, overwriteColors, visData.rows.length); const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, - // customTooltip: getTooltip( - // visData, - // metricFieldFormatter, - // bucketColumns, - // metricColumn - // ), }; + const legendPosition = visParams.legendPosition || Position.Right; + return (
@@ -358,8 +279,9 @@ const PieComponent = (props: PieComponentProps) => { { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 604f7e7ea9b0ce..6123a2e7d32463 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -20,7 +20,6 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; import { PieVisParams } from './types'; -import { vislibSlicesResponseHandler } from './utils'; export const vislibPieName = 'pie_vis'; @@ -31,7 +30,6 @@ interface Arguments { export interface RenderValue { visData: Datatable; visType: string; - visFormattedData: any; visConfig: PieVisParams; } @@ -58,14 +56,12 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ }, fn(context, args) { const visConfig = JSON.parse(args.visConfig) as PieVisParams; - const visFormattedData = vislibSlicesResponseHandler(context, visConfig.dimensions); return { type: 'render', as: vislibPieName, value: { visData: context, - visFormattedData, visConfig, visType: 'pie', params: { diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index f7690c61796d5f..baaec8902c5b29 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -39,7 +39,7 @@ export const pieVisRenderer: ExpressionRenderDefinition = { name: vislibPieName, displayName: 'Pie visualization', reuseDomNode: true, - render: (domNode, { visConfig, visData, visFormattedData }, handlers) => { + render: (domNode, { visConfig, visData }, handlers) => { const showNoResult = shouldShowNoResultsMessage(visData); const isSplitChart = Boolean(visConfig.dimensions.splitRow); @@ -51,7 +51,6 @@ export const pieVisRenderer: ExpressionRenderDefinition = { void; + color: string; +} + +export const ColorPicker = ({ onChange, color: selectedColor, id, label }: ColorPickerProps) => ( + +
+ + + +
+ {legendColors.map((color) => ( + onChange(color, e)} + onKeyPress={(e) => onChange(color, e)} + className={classNames('visColorPicker__valueDot', { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'visColorPicker__valueDot-isSelected': color === selectedColor, + })} + style={{ color }} + data-test-subj={`visColorPickerColor-${color}`} + /> + ))} +
+ {legendColors.some((c) => c === selectedColor) && ( + + onChange(null, e)} + onKeyPress={(e: any) => onChange(null, e)} + > + + + + )} +
+
+); diff --git a/src/plugins/vis_type_pie/public/components/index.ts b/src/plugins/vis_type_pie/public/temp/index.ts similarity index 94% rename from src/plugins/vis_type_pie/public/components/index.ts rename to src/plugins/vis_type_pie/public/temp/index.ts index fda1338ebb968f..6bd1bfd67b3c63 100644 --- a/src/plugins/vis_type_pie/public/components/index.ts +++ b/src/plugins/vis_type_pie/public/temp/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { getTooltip } from './tooltip'; +export { ColorPicker } from './color_picker'; diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/params.ts index 8f25833b945f4d..49a4c1f44e4479 100644 --- a/src/plugins/vis_type_pie/public/types/params.ts +++ b/src/plugins/vis_type_pie/public/types/params.ts @@ -82,6 +82,10 @@ export interface BucketColumns extends DatatableColumn { }; } +export interface EmptyBucket { + name: string; +} + export enum LabelPositions { INSIDE = 'inside', DEFAULT = 'default', diff --git a/src/plugins/vis_type_pie/public/utils/build_hierarchical_data.ts b/src/plugins/vis_type_pie/public/utils/build_hierarchical_data.ts deleted file mode 100644 index 88d0fe85482c13..00000000000000 --- a/src/plugins/vis_type_pie/public/utils/build_hierarchical_data.ts +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { toArray } from 'lodash'; -import { SerializedFieldFormat } from '../../../expressions/common/types'; -import { getFormatService } from '../services'; -import { Table } from '../types'; - -export interface Dimension { - accessor: number; - format: { - id?: string; - params?: SerializedFieldFormat; - }; -} - -export interface Dimensions { - metric: Dimension; - buckets?: Dimension[]; - splitRow?: Dimension[]; - splitColumn?: Dimension[]; -} - -interface Slice { - name: string; - size: number; - parent?: Slice; - children?: []; - rawData?: { - table: Table; - row: number; - column: number; - value: string | number | object; - }; -} - -export const buildHierarchicalData = (table: Table, { metric, buckets = [] }: Dimensions) => { - let slices: Slice[]; - const names: { [key: string]: string } = {}; - const metricColumn = table.columns[metric.accessor]; - const metricFieldFormatter = metric.format; - - if (!buckets.length) { - slices = [ - { - name: metricColumn.name, - size: table.rows[0][metricColumn.id] as number, - }, - ]; - names[metricColumn.name] = metricColumn.name; - } else { - slices = []; - table.rows.forEach((row, rowIndex) => { - let parent: Slice; - let dataLevel = slices; - - buckets.forEach((bucket) => { - const bucketColumn = table.columns[bucket.accessor]; - const bucketValueColumn = table.columns[bucket.accessor + 1]; - const bucketFormatter = getFormatService().deserialize(bucket.format); - const name = bucketFormatter.convert(row[bucketColumn.id]); - const size = row[bucketValueColumn.id] as number; - names[name] = name; - - let slice = dataLevel.find((dataLevelSlice) => dataLevelSlice.name === name); - if (!slice) { - slice = { - name, - size, - parent, - children: [], - rawData: { - table, - row: rowIndex, - column: bucket.accessor, - value: row[bucketColumn.id], - }, - }; - dataLevel.push(slice); - } - - parent = slice; - dataLevel = slice.children as []; - }); - }); - } - - return { - hits: table.rows.length, - raw: table, - names: toArray(names), - tooltipFormatter: metricFieldFormatter, - slices: { - children: [...slices], - }, - }; -}; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx new file mode 100644 index 00000000000000..7042b121bdae52 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -0,0 +1,69 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { BaseSyntheticEvent } from 'react'; + +import { LegendColorPicker, Position } from '@elastic/charts'; +import { PopoverAnchorPosition, EuiWrappingPopover } from '@elastic/eui'; + +import { ColorPicker } from '../temp'; + +function getAnchorPosition(legendPosition: Position): PopoverAnchorPosition { + switch (legendPosition) { + case Position.Bottom: + return 'upCenter'; + case Position.Top: + return 'downCenter'; + case Position.Left: + return 'rightCenter'; + default: + return 'leftCenter'; + } +} + +export const getColorPicker = ( + legendPosition: Position, + setColor: (newColor: string | null, seriesKey: string | number, event: BaseSyntheticEvent) => void +): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { + const seriesName = seriesIdentifier.key; + const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { + onClose(); + if (!seriesName) { + return; + } + if (newColor) { + onChange(newColor); + } + setColor(newColor, seriesName, event); + }; + + return ( + + + + ); +}; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts new file mode 100644 index 00000000000000..d01e547dcabd72 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -0,0 +1,95 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; +import { SeriesLayer } from '../../../charts/public'; +import { BucketColumns, PieVisParams } from '../types'; + +import { getFormatService, getColorsService } from '../services'; + +const EMPTY_SLICE = Symbol('empty_slice'); + +export const getLayers = ( + columns: Array>, + visParams: PieVisParams, + overwriteColors: { [key: string]: string }, + totalSeries: number +): PartitionLayer[] => { + const fillLabel: Partial = { + textInvertible: true, + valueFont: { + fontWeight: 700, + }, + }; + const defaultPalette = getColorsService().get('kibana_palette'); + + if (!visParams.labels.values) { + fillLabel.valueFormatter = () => ''; + } + return columns.map((col) => { + return { + groupByRollup: (d: Datum) => { + return col.id ? d[col.id] : col.name; + }, + showAccessor: (d: Datum) => d !== EMPTY_SLICE, + nodeLabel: (d: unknown) => { + if (col?.meta?.params) { + return getFormatService().deserialize(col.format).convert(d) ?? ''; + } + return String(d); + }, + fillLabel, + shape: { + fillColor: (d) => { + const seriesLayers: SeriesLayer[] = []; + + // Color is determined by round-robin on the index of the innermost slice + // This has to be done recursively until we get to the slice index + let tempParent: typeof d | typeof d['parent'] = d; + while (tempParent.parent && tempParent.depth > 0) { + seriesLayers.unshift({ + name: String(tempParent.parent.children[tempParent.sortIndex][0]), + rankAtDepth: tempParent.sortIndex, + totalSeriesAtDepth: tempParent.parent.children.length, + }); + tempParent = tempParent.parent; + } + + let overwriteColor; + seriesLayers.forEach((layer) => { + if (Object.keys(overwriteColors).includes(layer.name)) { + overwriteColor = overwriteColors[layer.name]; + } + }); + + const outputColor = defaultPalette.getColor( + seriesLayers, + { + behindText: visParams.labels.show, + maxDepth: columns.length, + totalSeries, + }, + overwriteColor + ); + + return outputColor || 'rgba(0,0,0,0)'; + }, + }, + }; + }); +}; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 8929f5d9f39dd4..54ee50729cae7a 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -17,4 +17,5 @@ * under the License. */ -export { vislibSlicesResponseHandler } from './response_handler'; +export { getLayers } from './get_layers'; +export { getColorPicker } from './get_color_picker'; diff --git a/src/plugins/vis_type_pie/public/utils/response_handler.js b/src/plugins/vis_type_pie/public/utils/response_handler.js deleted file mode 100644 index d3dee8612dc971..00000000000000 --- a/src/plugins/vis_type_pie/public/utils/response_handler.js +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { getFormatService } from '../services'; -import { buildHierarchicalData } from './build_hierarchical_data'; - -function tableResponseHandler(table, dimensions) { - const converted = { tables: [] }; - const split = dimensions.splitColumn || dimensions.splitRow; - - if (split) { - converted.direction = dimensions.splitRow ? 'row' : 'column'; - const splitColumnIndex = split[0].accessor; - const splitColumnFormatter = getFormatService().deserialize(split[0].format); - const splitColumn = table.columns[splitColumnIndex]; - const splitMap = {}; - let splitIndex = 0; - - table.rows.forEach((row, rowIndex) => { - const splitValue = row[splitColumn.id]; - - if (!splitMap.hasOwnProperty(splitValue)) { - splitMap[splitValue] = splitIndex++; - const tableGroup = { - $parent: converted, - title: `${splitColumnFormatter.convert(splitValue)}: ${splitColumn.name}`, - name: splitColumn.name, - key: splitValue, - column: splitColumnIndex, - row: rowIndex, - table, - tables: [], - }; - tableGroup.tables.push({ - $parent: tableGroup, - columns: table.columns, - rows: [], - }); - - converted.tables.push(tableGroup); - } - - const tableIndex = splitMap[splitValue]; - converted.tables[tableIndex].tables[0].rows.push(row); - }); - } else { - converted.tables.push({ - columns: table.columns, - rows: table.rows, - }); - } - - return converted; -} - -function convertTableGroup(tableGroup, convertTable) { - const tables = tableGroup.tables; - - if (!tables || !tables.length) return; - - const firstChild = tables[0]; - if (firstChild.columns) { - const chart = convertTable(firstChild); - // if chart is within a split, assign group title to its label - if (tableGroup.$parent) { - chart.label = tableGroup.title; - } - return chart; - } - - const out = {}; - let outList; - - tables.forEach(function (table) { - if (!outList) { - const direction = tableGroup.direction === 'row' ? 'rows' : 'columns'; - outList = out[direction] = []; - } - - let output; - if ((output = convertTableGroup(table, convertTable))) { - outList.push(output); - } - }); - - return out; -} - -function handlerFunction(convertTable) { - return function (response, dimensions) { - const tableGroup = tableResponseHandler(response, dimensions); - let converted = convertTableGroup(tableGroup, (table) => { - return convertTable(table, dimensions); - }); - if (!converted) { - // mimic a row of tables that doesn't have any tables - // https://github.com/elastic/kibana/blob/7bfb68cd24ed42b1b257682f93c50cd8d73e2520/src/kibana/components/vislib/components/zero_injection/inject_zeros.js#L32 - converted = { rows: [] }; - } - - converted.hits = response.rows.length; - - return converted; - }; -} - -export const vislibSlicesResponseHandler = handlerFunction(buildHierarchicalData); From 5407debcb434b3316ada68ddf8b01906f4bf7d3d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 19 Nov 2020 17:28:48 +0200 Subject: [PATCH 009/111] Fix ts error --- src/plugins/vis_type_pie/public/pie_component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 53b905740bbef6..62017dc4172093 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -166,7 +166,7 @@ const PieComponent = (props: PieComponentProps) => { props.uiState?.set('vis.legendOpen', newValue); return newValue; }); - }, [props.uiState?.set]); + }, [props.uiState]); const setColor = useCallback( (newColor: string | null, seriesLabel: string | number, event: BaseSyntheticEvent) => { @@ -185,7 +185,7 @@ const PieComponent = (props: PieComponentProps) => { props.uiState?.emit('colorChanged'); setOverwriteColors(colors); }, - [props.uiState?.emit, props.uiState?.get, props.uiState?.set, props.uiState?.setSilent] + [props.uiState] ); const { visData, visParams } = props; From 342245308fea57763c66e820e535755cdf37241f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 20 Nov 2020 12:27:34 +0200 Subject: [PATCH 010/111] Add legend actions --- src/plugins/vis_type_pie/public/chart.scss | 6 +- .../vis_type_pie/public/pie_component.tsx | 124 +++++++++-------- src/plugins/vis_type_pie/public/plugin.ts | 3 +- src/plugins/vis_type_pie/public/temp/index.ts | 1 + .../public/temp/legend_toggle.scss | 21 +++ .../public/temp/legend_toggle.tsx | 62 +++++++++ .../public/utils/get_legend_actions.tsx | 129 ++++++++++++++++++ .../vis_type_pie/public/utils/index.ts | 1 + 8 files changed, 291 insertions(+), 56 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/temp/legend_toggle.scss create mode 100644 src/plugins/vis_type_pie/public/temp/legend_toggle.tsx create mode 100644 src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index 6dd6b29e511a14..0acfefda84fc97 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -12,4 +12,8 @@ right: 0; bottom: 0; left: 0; -} \ No newline at end of file +} + +.pieChart__container .echLegendItem { + width: initial; +} diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 62017dc4172093..65e5a988172a01 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -40,6 +40,7 @@ import { RenderChangeListener, TooltipProps, TooltipType, + SeriesIdentifier, } from '@elastic/charts'; import { keys } from '@elastic/eui'; @@ -53,10 +54,9 @@ import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../ex import { ValueClickContext } from '../../embeddable/public'; import { PieVisParams, BucketColumns, LabelPositions, ValueFormats } from './types'; -import { getThemeService, getFormatService } from './services'; -import { getColorPicker, getLayers } from './utils'; -// import { colorSchemas } from 'src/plugins/charts/public'; -// import { ChartType } from '../common'; +import { getThemeService, getFormatService, getDataActions } from './services'; +import { getColorPicker, getLayers, getLegendActions, ClickTriggerEvent } from './utils'; +import { LegendToggle } from './temp'; import './chart.scss'; @@ -71,19 +71,8 @@ export interface PieComponentProps { export type PieComponentType = typeof PieComponent; const PieComponent = (props: PieComponentProps) => { - /** - * Stores all series labels to replicate vislib color map lookup - */ - // const allSeries: Array = []; const chartTheme = getThemeService().useChartsTheme(); const chartBaseTheme = getThemeService().useChartsBaseTheme(); - - // const [showLegend, setShowLegend] = useState(() => { - // // TODO: Check when this bwc can safely be removed - // const bwcLegendStateDefault = - // props.visParams.addLegend == null ? true : props.visParams.addLegend; - // return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; - // }); const [showLegend, setShowLegend] = useState(true); const [overwriteColors, setOverwriteColors] = useState(props.uiState?.get('vis.colors', {})); @@ -126,39 +115,58 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - // const getFilterEventData = useCallback( - // (visData: Datatable, xAccessor: string | number | null) => ( - // series: XYChartSeriesIdentifier - // ): ClickTriggerEvent | null => { - // if (xAccessor !== null) { - // return getFilterFromSeriesFn(visData)(series); - // } - - // return null; - // }, - // [] - // ); - - // const handleFilterAction = useCallback( - // (event: ClickTriggerEvent, negate = false) => { - // props.fireEvent({ - // ...event, - // data: { - // ...event.data, - // negate, - // }, - // }); - // }, - // [props] - // ); - - // const canFilter = async (event: ClickTriggerEvent | null): Promise => { - // if (!event) { - // return false; - // } - // const filters = await getDataActions().createFiltersFromValueClickAction(event.data); - // return Boolean(filters.length); - // }; + const getFilterEventData = useCallback( + (visData: Datatable) => (series: SeriesIdentifier): ClickTriggerEvent | null => { + // console.log(series.key); + const data = visData.columns.reduce( + (acc, { id }, column) => { + const value = series.key; + const row = visData.rows.findIndex((r) => r[id] === value); + if (row > -1) { + acc.push({ + table: visData, + column, + row, + value, + }); + } + + return acc; + }, + [] + ); + + return { + name: 'filterBucket', + data: { + negate: false, + data, + }, + }; + }, + [] + ); + + const handleFilterAction = useCallback( + (event: ClickTriggerEvent, negate = false) => { + props.fireEvent({ + ...event, + data: { + ...event.data, + negate, + }, + }); + }, + [props] + ); + + const canFilter = async (event: ClickTriggerEvent | null): Promise => { + if (!event) { + return false; + } + const filters = await getDataActions().createFiltersFromValueClickAction(event.data); + return Boolean(filters.length); + }; const toggleLegend = useCallback(() => { setShowLegend((value) => { @@ -266,16 +274,18 @@ const PieComponent = (props: PieComponentProps) => { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, }; - const legendPosition = visParams.legendPosition || Position.Right; + const legendPosition = useMemo(() => visParams.legendPosition ?? Position.Right, [ + visParams.legendPosition, + ]); return (
- {/* */} + { onElementClick={(args) => { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); }} + legendAction={getLegendActions( + canFilter, + getFilterEventData(visData), + handleFilterAction, + visParams + )} theme={chartTheme} baseTheme={chartBaseTheme} onRenderChange={onRenderChange} diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index be69ced3f39661..a9a4c7e7036ebb 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -24,7 +24,7 @@ import { DataPublicPluginStart } from '../../data/public'; import { createPieVisFn } from './pie_fn'; import { pieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; -import { setThemeService, setColorsService, setFormatService } from './services'; +import { setThemeService, setColorsService, setFormatService, setDataActions } from './services'; export interface VisTypePieSetupDependencies { visualizations: VisualizationsSetup; @@ -58,5 +58,6 @@ export class VisTypePiePlugin { start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) { setFormatService(data.fieldFormats); + setDataActions(data.actions); } } diff --git a/src/plugins/vis_type_pie/public/temp/index.ts b/src/plugins/vis_type_pie/public/temp/index.ts index 6bd1bfd67b3c63..d53b20b195da89 100644 --- a/src/plugins/vis_type_pie/public/temp/index.ts +++ b/src/plugins/vis_type_pie/public/temp/index.ts @@ -18,3 +18,4 @@ */ export { ColorPicker } from './color_picker'; +export { LegendToggle } from './legend_toggle'; diff --git a/src/plugins/vis_type_pie/public/temp/legend_toggle.scss b/src/plugins/vis_type_pie/public/temp/legend_toggle.scss new file mode 100644 index 00000000000000..d372b8d9df6aa6 --- /dev/null +++ b/src/plugins/vis_type_pie/public/temp/legend_toggle.scss @@ -0,0 +1,21 @@ +.echLegend__toggle { + position: absolute; + bottom: 0; + left: 0; + z-index: 1; + margin: $euiSizeXS; + + &--isOpen { + background-color: $euiColorLightestShade; + } + + &--position-left, + &--position-bottom { + left: auto; + bottom: auto; + right: 0; + top: 0; + } + } + + \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx b/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx new file mode 100644 index 00000000000000..12742b6da6e6bd --- /dev/null +++ b/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { memo, useMemo } from 'react'; +import classNames from 'classnames'; + +import { i18n } from '@kbn/i18n'; +import { htmlIdGenerator, EuiButtonIcon } from '@elastic/eui'; +import { Position } from '@elastic/charts'; + +import './legend_toggle.scss'; + +interface LegendToggleProps { + onClick: () => void; + showLegend: boolean; + legendPosition: Position; +} + +const LegendToggleComponent = ({ onClick, showLegend, legendPosition }: LegendToggleProps) => { + const legendId = useMemo(() => htmlIdGenerator()('legend'), []); + + return ( + + ); +}; + +export const LegendToggle = memo(LegendToggleComponent); diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx new file mode 100644 index 00000000000000..50073ed37cf715 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -0,0 +1,129 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useState } from 'react'; + +import { i18n } from '@kbn/i18n'; +import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; +import { LegendAction, SeriesIdentifier } from '@elastic/charts'; +import { ValueClickContext } from '../../../embeddable/public'; +import { PieVisParams } from '../types'; +import { getFormatService } from '../services'; + +// import { ClickTriggerEvent } from '../../../charts/public'; + +// this is temporary +export interface ClickTriggerEvent { + name: 'filterBucket'; + data: ValueClickContext['data']; +} + +export const getLegendActions = ( + canFilter: (data: ClickTriggerEvent | null) => Promise, + getFilterEventData: (series: SeriesIdentifier) => ClickTriggerEvent | null, + onFilter: (data: ClickTriggerEvent, negate?: any) => void, + visParams: PieVisParams +): LegendAction => { + return ({ series }) => { + const [popoverOpen, setPopoverOpen] = useState(false); + const [isfilterable, setIsfilterable] = useState(true); + const filterData = getFilterEventData(series); + + (async () => setIsfilterable(await canFilter(filterData)))(); + + if (!isfilterable || !filterData) { + return null; + } + + let formattedTitle = ''; + if (visParams.dimensions.buckets) { + const column = visParams.dimensions?.buckets.find( + (bucket) => bucket.accessor === filterData.data.data[0].column + ); + formattedTitle = getFormatService().deserialize(column?.format).convert(series.key) ?? ''; + } + + const title = formattedTitle || series.key; + const panels: EuiContextMenuPanelDescriptor[] = [ + { + id: 'main', + title: `${title}`, + items: [ + { + name: i18n.translate('visTypePie.legend.filterForValueButtonAriaLabel', { + defaultMessage: 'Filter for value', + }), + 'data-test-subj': `legend-${title}-filterIn`, + icon: , + onClick: () => { + setPopoverOpen(false); + onFilter(filterData); + }, + }, + { + name: i18n.translate('visTypePie.legend.filterOutValueButtonAriaLabel', { + defaultMessage: 'Filter out value', + }), + 'data-test-subj': `legend-${title}-filterOut`, + icon: , + onClick: () => { + setPopoverOpen(false); + onFilter(filterData, true); + }, + }, + ], + }, + ]; + + const Button = ( +
undefined} + onClick={() => setPopoverOpen(!popoverOpen)} + > + +
+ ); + + return ( + setPopoverOpen(false)} + panelPaddingSize="none" + anchorPosition="upLeft" + title={i18n.translate('visTypePie.legend.filterOptionsLegend', { + defaultMessage: '{legendDataLabel}, filter options', + values: { legendDataLabel: title }, + })} + > + + + ); + }; +}; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 54ee50729cae7a..862c72f849d775 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -19,3 +19,4 @@ export { getLayers } from './get_layers'; export { getColorPicker } from './get_color_picker'; +export { getLegendActions, ClickTriggerEvent } from './get_legend_actions'; From f1ee28342debc229be373dc58bc30095cfa2ffa7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 20 Nov 2020 14:01:31 +0200 Subject: [PATCH 011/111] Fix bug on Color Picker and remove local state as it is unecessary --- src/plugins/vis_type_pie/public/pie_component.tsx | 11 +++++++---- .../vis_type_pie/public/utils/get_color_picker.tsx | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 65e5a988172a01..583279b8381458 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -74,7 +74,6 @@ const PieComponent = (props: PieComponentProps) => { const chartTheme = getThemeService().useChartsTheme(); const chartBaseTheme = getThemeService().useChartsBaseTheme(); const [showLegend, setShowLegend] = useState(true); - const [overwriteColors, setOverwriteColors] = useState(props.uiState?.get('vis.colors', {})); const onRenderChange = useCallback( (isRendered) => { @@ -190,8 +189,7 @@ const PieComponent = (props: PieComponentProps) => { } props.uiState?.setSilent('vis.colors', null); props.uiState?.set('vis.colors', colors); - props.uiState?.emit('colorChanged'); - setOverwriteColors(colors); + props.uiState?.emit('reload'); }, [props.uiState] ); @@ -268,7 +266,12 @@ const PieComponent = (props: PieComponentProps) => { }); } - const layers = getLayers(layersColumns, visParams, overwriteColors, visData.rows.length); + const layers = getLayers( + layersColumns, + visParams, + props.uiState?.get('vis.colors', {}), + visData.rows.length + ); const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 7042b121bdae52..2f9deb9ec8dc2b 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -18,7 +18,7 @@ */ import React, { BaseSyntheticEvent } from 'react'; - +import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; import { PopoverAnchorPosition, EuiWrappingPopover } from '@elastic/eui'; @@ -52,6 +52,7 @@ export const getColorPicker = ( } setColor(newColor, seriesName, event); }; + const hexColor = new Color(color).hex(); return ( - + ); }; From 2fd26cce4bc87c71aeb91d7478abab536a7ccccc Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 20 Nov 2020 18:10:10 +0200 Subject: [PATCH 012/111] Fix some bugs on colorPicker --- .../vis_type_pie/public/pie_component.tsx | 2 +- .../vis_type_pie/public/temp/color_picker.tsx | 14 ++++++- src/plugins/vis_type_pie/public/temp/index.ts | 1 + .../vis_type_pie/public/temp/lighten_color.ts | 37 +++++++++++++++++++ .../public/utils/get_color_picker.tsx | 13 ++++--- 5 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/temp/lighten_color.ts diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 583279b8381458..00ab4411b3490e 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -294,7 +294,7 @@ const PieComponent = (props: PieComponentProps) => { showLegend={showLegend} legendPosition={legendPosition} legendMaxDepth={visParams.nestedLegend ? undefined : 1} - legendColorPicker={getColorPicker(legendPosition, setColor)} + legendColorPicker={getColorPicker(legendPosition, setColor, layersColumns.length)} tooltip={tooltip} onElementClick={(args) => { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); diff --git a/src/plugins/vis_type_pie/public/temp/color_picker.tsx b/src/plugins/vis_type_pie/public/temp/color_picker.tsx index 5ff22ae3f3c56d..d8a903026bcaba 100644 --- a/src/plugins/vis_type_pie/public/temp/color_picker.tsx +++ b/src/plugins/vis_type_pie/public/temp/color_picker.tsx @@ -22,6 +22,7 @@ import React, { BaseSyntheticEvent } from 'react'; import { EuiButtonEmpty, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { lightenColor } from './lighten_color'; import './color_picker.scss'; @@ -89,9 +90,16 @@ interface ColorPickerProps { label: string | number | null; onChange: (color: string | null, event: BaseSyntheticEvent) => void; color: string; + maxDepth: number; } -export const ColorPicker = ({ onChange, color: selectedColor, id, label }: ColorPickerProps) => ( +export const ColorPicker = ({ + onChange, + color: selectedColor, + id, + label, + maxDepth, +}: ColorPickerProps) => (
@@ -124,7 +132,9 @@ export const ColorPicker = ({ onChange, color: selectedColor, id, label }: Color /> ))}
- {legendColors.some((c) => c === selectedColor) && ( + {legendColors.some( + (c) => c === selectedColor || lightenColor(c, maxDepth, maxDepth) === selectedColor + ) && ( void + setColor: ( + newColor: string | null, + seriesKey: string | number, + event: BaseSyntheticEvent + ) => void, + maxDepth: number ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { onClose(); - if (!seriesName) { - return; - } if (newColor) { onChange(newColor); } setColor(newColor, seriesName, event); }; const hexColor = new Color(color).hex(); - return ( - + ); }; From e5cfa42c5c82d55de5262a28818a4ae6bb3c35bb Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 25 Nov 2020 17:17:06 +0200 Subject: [PATCH 013/111] Add setting for the user to select between the legacy palette or the eui ones --- .../public/services/palettes/palettes.tsx | 19 +++-- .../vis_type_pie/public/editor/collections.ts | 2 +- .../editor/components/palette_picker.tsx | 77 +++++++++++++++++++ .../public/editor/components/pie.tsx | 17 +++- .../vis_type_pie/public/pie_component.tsx | 14 +++- .../vis_type_pie/public/types/params.ts | 3 + .../public/utils/get_color_picker.tsx | 22 +++++- .../vis_type_pie/public/utils/get_layers.ts | 5 +- .../vis_type_pie/public/vis_type/pie.ts | 12 ++- 9 files changed, 153 insertions(+), 18 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx diff --git a/src/plugins/charts/public/services/palettes/palettes.tsx b/src/plugins/charts/public/services/palettes/palettes.tsx index 69f951fa6caa4f..1fac2b405704f4 100644 --- a/src/plugins/charts/public/services/palettes/palettes.tsx +++ b/src/plugins/charts/public/services/palettes/palettes.tsx @@ -43,11 +43,17 @@ function buildRoundRobinCategoricalWithMappedColors(): Omit { function getColor( series: SeriesLayer[], - chartConfiguration: ChartColorConfiguration = { behindText: false } + chartConfiguration: ChartColorConfiguration = { behindText: false }, + state?: unknown ) { const totalSeriesAtDepth = series[0].totalSeriesAtDepth; const rankAtDepth = series[0].rankAtDepth; const actualColors = colors(totalSeriesAtDepth); - const outputColor = actualColors[rankAtDepth]; + const outputColor = (state as string) ?? actualColors[rankAtDepth]; if (!chartConfiguration.maxDepth || chartConfiguration.maxDepth === 1) { return outputColor; diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts index 3a740eff42b931..c4d3b3b4a33834 100644 --- a/src/plugins/vis_type_pie/public/editor/collections.ts +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -66,7 +66,7 @@ export const getLabelPositions = () => [ export const getValuesFormats = () => [ { text: i18n.translate('visTypePie.valuesFormats.percent', { - defaultMessage: 'Show Percent', + defaultMessage: 'Show percent', }), value: ValueFormats.PERCENT, }, diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx new file mode 100644 index 00000000000000..7a4747039e0d37 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx @@ -0,0 +1,77 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { PaletteOutput } from 'src/plugins/charts/public'; +import { EuiColorPalettePicker } from '@elastic/eui'; +import { EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { getColorsService } from '../../services'; + +interface PalettePickerProps { + 'data-test-subj'?: string; + activePalette?: PaletteOutput; + paramName: ParamName; + setPalette: (paramName: ParamName, value: PaletteOutput) => void; + disabled?: boolean; +} + +export function PalettePicker({ + activePalette, + paramName, + setPalette, + disabled, +}: PalettePickerProps) { + return ( + + !internal) + .map(({ id, title, getColors }) => { + return { + value: id, + title, + type: 'fixed', + palette: getColors( + 10, + id === activePalette?.name ? activePalette?.params : undefined + ), + }; + })} + onChange={(newPalette) => { + setPalette(paramName, { + type: 'palette', + name: newPalette, + }); + }} + valueOfSelected={activePalette?.name || 'default'} + selectionDisplay={'palette'} + /> + + ); +} diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 345c9adc9e80a0..4679d8b6436708 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -24,6 +24,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; +import { PalettePicker } from './palette_picker'; import { BasicOptions, SwitchOption, SelectOption } from '../../../../charts/public'; import { PieVisParams } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; @@ -58,12 +59,26 @@ function PieOptions(props: VisOptionsProps) { + + diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 00ab4411b3490e..7359558e963522 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -266,11 +266,14 @@ const PieComponent = (props: PieComponentProps) => { }); } + const palette = visParams.legacyPalette ? 'kibana_palette' : visParams.palette.name; + const layers = getLayers( layersColumns, visParams, props.uiState?.get('vis.colors', {}), - visData.rows.length + visData.rows.length, + palette ); const tooltip: TooltipProps = { @@ -294,7 +297,14 @@ const PieComponent = (props: PieComponentProps) => { showLegend={showLegend} legendPosition={legendPosition} legendMaxDepth={visParams.nestedLegend ? undefined : 1} - legendColorPicker={getColorPicker(legendPosition, setColor, layersColumns.length)} + legendColorPicker={getColorPicker( + legendPosition, + setColor, + layersColumns.length, + visParams.legacyPalette, + bucketColumns[0], + visData.rows + )} tooltip={tooltip} onElementClick={(args) => { handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/params.ts index 49a4c1f44e4479..021adac0479af6 100644 --- a/src/plugins/vis_type_pie/public/types/params.ts +++ b/src/plugins/vis_type_pie/public/types/params.ts @@ -18,6 +18,7 @@ */ import { Position } from '@elastic/charts'; import { DatatableColumn } from '../../../expressions/public'; +import { PaletteOutput } from '../../../charts/public'; export interface Dimension { accessor: number; @@ -42,6 +43,8 @@ export interface PieVisParams { nestedLegend: boolean; dimensions: Dimensions; isDonut: boolean; + palette: PaletteOutput; + legacyPalette: boolean; labels: { show: boolean; position: LabelPositions; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 1e97dd25f52ce4..6393d0de6f8eec 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -21,7 +21,8 @@ import React, { BaseSyntheticEvent } from 'react'; import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; import { PopoverAnchorPosition, EuiWrappingPopover } from '@elastic/eui'; - +import { DatatableRow } from '../../../expressions/public'; +import { BucketColumns } from '../types'; import { ColorPicker } from '../temp'; function getAnchorPosition(legendPosition: Position): PopoverAnchorPosition { @@ -37,6 +38,14 @@ function getAnchorPosition(legendPosition: Position): PopoverAnchorPosition { } } +function isOnInnerLayer( + firstBucket: BucketColumns, + data: DatatableRow[], + seriesKey: string +): DatatableRow | undefined { + return data.find((d) => d[firstBucket.id] === seriesKey); +} + export const getColorPicker = ( legendPosition: Position, setColor: ( @@ -44,7 +53,10 @@ export const getColorPicker = ( seriesKey: string | number, event: BaseSyntheticEvent ) => void, - maxDepth: number + maxDepth: number, + isLegacyPaletteEnabled: boolean, + firstBucket: BucketColumns, + data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { @@ -54,6 +66,12 @@ export const getColorPicker = ( } setColor(newColor, seriesName, event); }; + + // For the EuiPalette we want the user to be able to change only the colors of the inner layer + if (!isLegacyPaletteEnabled) { + const enablePicker = isOnInnerLayer(firstBucket, data, seriesIdentifier.key); + if (!enablePicker) return null; + } const hexColor = new Color(color).hex(); return ( >, visParams: PieVisParams, overwriteColors: { [key: string]: string }, - totalSeries: number + totalSeries: number, + palette: string ): PartitionLayer[] => { const fillLabel: Partial = { textInvertible: true, @@ -36,7 +37,7 @@ export const getLayers = ( fontWeight: 700, }, }; - const defaultPalette = getColorsService().get('kibana_palette'); + const defaultPalette = getColorsService().get(palette); if (!visParams.labels.values) { fillLabel.valueFormatter = () => ''; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 0c1a8e9787cbdf..95abcfd2923bd0 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -49,6 +49,11 @@ export const getPieVisTypeDefinition = ( legendPosition: Position.Right, nestedLegend: false, isDonut: true, + legacyPalette: false, + palette: { + type: 'palette', + name: 'default', + }, labels: { show: true, values: true, @@ -67,7 +72,7 @@ export const getPieVisTypeDefinition = ( { group: AggGroupNames.Metrics, name: 'metric', - title: i18n.translate('visTypeVislib.pie.metricTitle', { + title: i18n.translate('visTypePie.pie.metricTitle', { defaultMessage: 'Slice size', }), min: 1, @@ -78,7 +83,7 @@ export const getPieVisTypeDefinition = ( { group: AggGroupNames.Buckets, name: 'segment', - title: i18n.translate('visTypeVislib.pie.segmentTitle', { + title: i18n.translate('visTypePie.pie.segmentTitle', { defaultMessage: 'Split slices', }), min: 0, @@ -88,7 +93,7 @@ export const getPieVisTypeDefinition = ( { group: AggGroupNames.Buckets, name: 'split', - title: i18n.translate('visTypeVislib.pie.splitTitle', { + title: i18n.translate('visTypePie.pie.splitTitle', { defaultMessage: 'Split chart', }), mustBeFirst: true, @@ -99,5 +104,4 @@ export const getPieVisTypeDefinition = ( ]), }, hierarchicalData: true, - responseHandler: 'vislib_slices', }); From 9483b1c1926a50b950de7d40a494e91b228a3cec Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 26 Nov 2020 14:14:08 +0200 Subject: [PATCH 014/111] small enhancements, treat empty labels with (empty) --- .../public/__snapshots__/to_ast.test.ts.snap | 19 ++++++++ .../vis_type_pie/public/editor/collections.ts | 28 ----------- .../public/editor/components/pie.tsx | 9 ---- .../vis_type_pie/public/editor/index.ts | 3 +- .../vis_type_pie/public/editor/positions.ts | 48 +++++++++++++++++++ .../vis_type_pie/public/pie_component.tsx | 4 +- .../vis_type_pie/public/types/params.ts | 1 - .../public/utils/get_color_picker.tsx | 4 +- .../vis_type_pie/public/utils/get_layers.ts | 6 +++ .../vis_type_pie/public/vis_type/pie.ts | 4 +- 10 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap create mode 100644 src/plugins/vis_type_pie/public/editor/positions.ts diff --git a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 00000000000000..54607960b2e8a6 --- /dev/null +++ b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`pie vis toExpressionAst function should match basic snapshot 1`] = ` +Object { + "addArgument": [Function], + "arguments": Object { + "visConfig": Array [ + "{\\"type\\":\\"pie\\",\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"right\\",\\"isDonut\\":true,\\"labels\\":{\\"show\\":true,\\"values\\":true,\\"last_level\\":true,\\"truncate\\":100},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\"},\\"params\\":{}},\\"buckets\\":[{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}", + ], + }, + "getArgument": [Function], + "name": "pie_vis", + "removeArgument": [Function], + "replaceArgument": [Function], + "toAst": [Function], + "toString": [Function], + "type": "expression_function_builder", +} +`; diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts index c4d3b3b4a33834..5df4a40f3060b0 100644 --- a/src/plugins/vis_type_pie/public/editor/collections.ts +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -18,36 +18,8 @@ */ import { i18n } from '@kbn/i18n'; -import { Position } from '@elastic/charts'; import { LabelPositions, ValueFormats } from '../types'; -export const getLegendPositions = () => [ - { - text: i18n.translate('visTypePie.legendPositions.topText', { - defaultMessage: 'Top', - }), - value: Position.Top, - }, - { - text: i18n.translate('visTypePie.legendPositions.leftText', { - defaultMessage: 'Left', - }), - value: Position.Left, - }, - { - text: i18n.translate('visTypePie.legendPositions.rightText', { - defaultMessage: 'Right', - }), - value: Position.Right, - }, - { - text: i18n.translate('visTypePie.legendPositions.bottomText', { - defaultMessage: 'Bottom', - }), - value: Position.Bottom, - }, -]; - export const getLabelPositions = () => [ { text: i18n.translate('visTypePie.labelPositions.insideText', { diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 4679d8b6436708..64897b1af8c34c 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -65,16 +65,7 @@ function PieOptions(props: VisOptionsProps) { value={stateParams.nestedLegend} setValue={setValue} /> - [ + { + text: i18n.translate('visTypePie.legendPositions.topText', { + defaultMessage: 'Top', + }), + value: Position.Top, + }, + { + text: i18n.translate('visTypePie.legendPositions.leftText', { + defaultMessage: 'Left', + }), + value: Position.Left, + }, + { + text: i18n.translate('visTypePie.legendPositions.rightText', { + defaultMessage: 'Right', + }), + value: Position.Right, + }, + { + text: i18n.translate('visTypePie.legendPositions.bottomText', { + defaultMessage: 'Bottom', + }), + value: Position.Bottom, + }, +]; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 7359558e963522..1d42e0a810e834 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -266,7 +266,7 @@ const PieComponent = (props: PieComponentProps) => { }); } - const palette = visParams.legacyPalette ? 'kibana_palette' : visParams.palette.name; + const palette = visParams.palette.name; const layers = getLayers( layersColumns, @@ -301,7 +301,7 @@ const PieComponent = (props: PieComponentProps) => { legendPosition, setColor, layersColumns.length, - visParams.legacyPalette, + visParams.palette.name, bucketColumns[0], visData.rows )} diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/params.ts index 021adac0479af6..bdee5f7365cf1e 100644 --- a/src/plugins/vis_type_pie/public/types/params.ts +++ b/src/plugins/vis_type_pie/public/types/params.ts @@ -44,7 +44,6 @@ export interface PieVisParams { dimensions: Dimensions; isDonut: boolean; palette: PaletteOutput; - legacyPalette: boolean; labels: { show: boolean; position: LabelPositions; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 6393d0de6f8eec..91c87379c61a6d 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -54,7 +54,7 @@ export const getColorPicker = ( event: BaseSyntheticEvent ) => void, maxDepth: number, - isLegacyPaletteEnabled: boolean, + palette: string, firstBucket: BucketColumns, data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { @@ -68,7 +68,7 @@ export const getColorPicker = ( }; // For the EuiPalette we want the user to be able to change only the colors of the inner layer - if (!isLegacyPaletteEnabled) { + if (palette !== 'kibana_palette') { const enablePicker = isOnInnerLayer(firstBucket, data, seriesIdentifier.key); if (!enablePicker) return null; } diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index b0cf77ad648a05..b98d89dd753472 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ +import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; import { SeriesLayer } from '../../../charts/public'; import { BucketColumns, PieVisParams } from '../types'; @@ -49,6 +50,11 @@ export const getLayers = ( }, showAccessor: (d: Datum) => d !== EMPTY_SLICE, nodeLabel: (d: unknown) => { + if (d === '') { + return i18n.translate('visTypePie.emptyLabelValue', { + defaultMessage: '(empty)', + }); + } if (col?.meta?.params) { return getFormatService().deserialize(col.format).convert(d) ?? ''; } diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 95abcfd2923bd0..a724848ff2fbb0 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -28,7 +28,8 @@ import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualization import { PieVisParams, LabelPositions, ValueFormats } from '../types'; import { toExpressionAst } from '../to_ast'; -import { getLegendPositions, PieOptions } from '../editor'; +import { getLegendPositions } from '../editor'; +import { PieOptions } from '../editor/components'; export const getPieVisTypeDefinition = ( showElasticChartsOptions = false @@ -49,7 +50,6 @@ export const getPieVisTypeDefinition = ( legendPosition: Position.Right, nestedLegend: false, isDonut: true, - legacyPalette: false, palette: { type: 'palette', name: 'default', From 2ddcf2f494775eefd4a943c71742fb8a5a2be866 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 26 Nov 2020 16:24:01 +0200 Subject: [PATCH 015/111] Fix color picker bugs with multiple layers --- .../public/services/palettes/palettes.tsx | 27 ++++++------------- .../vis_type_pie/public/pie_component.tsx | 3 +-- .../vis_type_pie/public/temp/color_picker.tsx | 4 ++- .../public/utils/get_color_picker.tsx | 27 ++++++++++++++----- .../vis_type_pie/public/utils/get_layers.ts | 20 +++++++------- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/plugins/charts/public/services/palettes/palettes.tsx b/src/plugins/charts/public/services/palettes/palettes.tsx index 1fac2b405704f4..c1fd7c3cc739fd 100644 --- a/src/plugins/charts/public/services/palettes/palettes.tsx +++ b/src/plugins/charts/public/services/palettes/palettes.tsx @@ -43,17 +43,11 @@ function buildRoundRobinCategoricalWithMappedColors(): Omit { function getColor( series: SeriesLayer[], - chartConfiguration: ChartColorConfiguration = { behindText: false }, - state?: unknown + chartConfiguration: ChartColorConfiguration = { behindText: false } ) { const totalSeriesAtDepth = series[0].totalSeriesAtDepth; const rankAtDepth = series[0].rankAtDepth; const actualColors = colors(totalSeriesAtDepth); - const outputColor = (state as string) ?? actualColors[rankAtDepth]; + const outputColor = actualColors[rankAtDepth]; if (!chartConfiguration.maxDepth || chartConfiguration.maxDepth === 1) { return outputColor; @@ -122,13 +115,9 @@ function buildGradient( function buildSyncedKibanaPalette( colors: ChartsPluginSetup['legacyColors'] ): Omit { - function getColor( - series: SeriesLayer[], - chartConfiguration: ChartColorConfiguration = {}, - state?: unknown - ) { + function getColor(series: SeriesLayer[], chartConfiguration: ChartColorConfiguration = {}) { colors.mappedColors.mapKeys([series[0].name]); - const outputColor = state ?? colors.mappedColors.get(series[0].name); + const outputColor = colors.mappedColors.get(series[0].name); if (!chartConfiguration.maxDepth || chartConfiguration.maxDepth === 1) { return outputColor; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 1d42e0a810e834..ab1a9ae75fe9b8 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -300,9 +300,8 @@ const PieComponent = (props: PieComponentProps) => { legendColorPicker={getColorPicker( legendPosition, setColor, - layersColumns.length, + layersColumns, visParams.palette.name, - bucketColumns[0], visData.rows )} tooltip={tooltip} diff --git a/src/plugins/vis_type_pie/public/temp/color_picker.tsx b/src/plugins/vis_type_pie/public/temp/color_picker.tsx index d8a903026bcaba..3cb46eab6633a9 100644 --- a/src/plugins/vis_type_pie/public/temp/color_picker.tsx +++ b/src/plugins/vis_type_pie/public/temp/color_picker.tsx @@ -91,6 +91,7 @@ interface ColorPickerProps { onChange: (color: string | null, event: BaseSyntheticEvent) => void; color: string; maxDepth: number; + layerIndex: number; } export const ColorPicker = ({ @@ -99,6 +100,7 @@ export const ColorPicker = ({ id, label, maxDepth, + layerIndex, }: ColorPickerProps) => (
@@ -133,7 +135,7 @@ export const ColorPicker = ({ ))}
{legendColors.some( - (c) => c === selectedColor || lightenColor(c, maxDepth, maxDepth) === selectedColor + (c) => c === selectedColor || lightenColor(c, layerIndex, maxDepth) === selectedColor ) && ( > +): number { + const row = data.find((d) => Object.keys(d).find((key) => d[key] === seriesKey)); + const bucketId = row && Object.keys(row).find((key) => row[key] === seriesKey); + return layers.findIndex((layer) => layer.id === bucketId) + 1; +} + function isOnInnerLayer( - firstBucket: BucketColumns, + firstBucket: Partial, data: DatatableRow[], seriesKey: string ): DatatableRow | undefined { - return data.find((d) => d[firstBucket.id] === seriesKey); + return data.find((d) => firstBucket.id && d[firstBucket.id] === seriesKey); } export const getColorPicker = ( @@ -53,9 +63,8 @@ export const getColorPicker = ( seriesKey: string | number, event: BaseSyntheticEvent ) => void, - maxDepth: number, + layerColumns: Array>, palette: string, - firstBucket: BucketColumns, data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { const seriesName = seriesIdentifier.key; @@ -69,7 +78,7 @@ export const getColorPicker = ( // For the EuiPalette we want the user to be able to change only the colors of the inner layer if (palette !== 'kibana_palette') { - const enablePicker = isOnInnerLayer(firstBucket, data, seriesIdentifier.key); + const enablePicker = isOnInnerLayer(layerColumns[0], data, seriesName); if (!enablePicker) return null; } const hexColor = new Color(color).hex(); @@ -83,7 +92,13 @@ export const getColorPicker = ( closePopover={onClose} panelPaddingSize="s" > - +
); }; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index b98d89dd753472..1f30571a79972d 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; import { SeriesLayer } from '../../../charts/public'; import { BucketColumns, PieVisParams } from '../types'; - +import { lightenColor } from '../temp'; import { getFormatService, getColorsService } from '../services'; const EMPTY_SLICE = Symbol('empty_slice'); @@ -84,15 +84,15 @@ export const getLayers = ( } }); - const outputColor = defaultPalette.getColor( - seriesLayers, - { - behindText: visParams.labels.show, - maxDepth: columns.length, - totalSeries, - }, - overwriteColor - ); + if (overwriteColor) { + return lightenColor(overwriteColor, seriesLayers.length, columns.length); + } + + const outputColor = defaultPalette.getColor(seriesLayers, { + behindText: visParams.labels.show, + maxDepth: columns.length, + totalSeries, + }); return outputColor || 'rgba(0,0,0,0)'; }, From c43dbe2b4140d0fb20d5e95bb3f049f19c7190c4 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 30 Nov 2020 09:46:18 +0200 Subject: [PATCH 016/111] fixes on internationalization --- .../public/__snapshots__/pie_fn.test.ts.snap | 51 +++++++++++++++ .../editor/components/palette_picker.tsx | 4 +- .../editor/components/truncate_labels.tsx | 4 +- .../vis_type_pie/public/pie_fn.test.ts | 62 +++++++++++++++++++ .../vis_type_pie/public/to_ast_esaggs.ts | 1 + 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap create mode 100644 src/plugins/vis_type_pie/public/pie_fn.test.ts diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap new file mode 100644 index 00000000000000..8f39e4ce5af424 --- /dev/null +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`interpreter/functions#pie returns an object with the correct structure 1`] = ` +Object { + "as": "pie_vis", + "type": "render", + "value": Object { + "params": Object { + "listenOnChange": true, + }, + "visConfig": Object { + "addLegend": true, + "addTooltip": true, + "dimensions": Object { + "metric": Object { + "accessor": 0, + "aggType": "count", + "format": Object { + "id": "number", + }, + "params": Object {}, + }, + }, + "isDonut": true, + "labels": Object { + "last_level": true, + "show": false, + "truncate": 100, + "values": true, + }, + "legendPosition": "right", + "type": "pie", + }, + "visData": Object { + "columns": Array [ + Object { + "id": "col-0-1", + "name": "Count", + }, + ], + "rows": Array [ + Object { + "col-0-1": 0, + }, + ], + "type": "datatable", + }, + "visType": "pie", + }, +} +`; diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx index 7a4747039e0d37..02ac494e50ced0 100644 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx @@ -41,13 +41,13 @@ export function PalettePicker({ return ( { + const fn = functionWrapper(createPieVisFn()); + const context = { + type: 'datatable', + rows: [{ 'col-0-1': 0 }], + columns: [{ id: 'col-0-1', name: 'Count' }], + }; + const visConfig = { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: 'right', + isDonut: true, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, + dimensions: { + metric: { + accessor: 0, + format: { + id: 'number', + }, + params: {}, + aggType: 'count', + }, + }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns an object with the correct structure', async () => { + const actual = await fn(context, { visConfig: JSON.stringify(visConfig) }); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts index 047a626032edab..1a0418251b960d 100644 --- a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts +++ b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts @@ -26,6 +26,7 @@ import { PieVisParams } from './types'; /** * Get esaggs expressions function * TODO: replace this with vis.data.aggs!.toExpressionAst(); + * https://github.com/elastic/kibana/issues/61768 * @param vis */ export function getEsaggsFn(vis: Vis) { From 931557fd850389e784f0fd681b22ab33e338120c Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 30 Nov 2020 14:48:42 +0200 Subject: [PATCH 017/111] Create migration script for pie chart and legacy palette --- .../visualization_migrations.test.ts | 42 +++++++++++++++++++ .../saved_objects/visualization_migrations.ts | 34 +++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index c4ee92194ec361..2fc51426e306d0 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1654,4 +1654,46 @@ describe('migration visualization', () => { expect(attributes).toEqual(oldAttributes); }); }); + + describe('7.12.0 update vislib pie defaults', () => { + const migrate = (doc: any) => + visualizationSavedObjectTypeMigrations['7.12.0']( + doc as Parameters[0], + savedObjectMigrationContext + ); + const generateDoc = (type = 'pie') => ({ + attributes: { + type, + title: 'My Vis', + description: 'This is my super cool vis.', + visState: JSON.stringify({ + type, + title: 'My pie vis', + params: { + type, + addLegend: true, + addTooltip: true, + isDonut: true, + labels: { + show: true, + truncate: 100, + }, + }, + }), + }, + }); + + it('should return original doc if is not a pie chart', () => { + const doc = generateDoc('area'); + const migratedTestDoc = migrate(doc); + expect(migratedTestDoc).toEqual(doc); + }); + + it('should decorate existing docs with the kibana legacy palette', () => { + const migratedTestDoc = migrate(generateDoc()); + const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(palette.name).toEqual('kibana_palette'); + }); + }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index fbeefacf6035fd..14476dfdf5d227 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -757,6 +757,39 @@ const removeTSVBSearchSource: SavedObjectMigrationFn = (doc) => { return doc; }; +// [Pie Chart] Migrate vislib pie chart to use the new plugin vis_type_pie +const migrateVislibPie: SavedObjectMigrationFn = (doc) => { + const visStateJSON = get(doc, 'attributes.visState'); + let visState; + + if (visStateJSON) { + try { + visState = JSON.parse(visStateJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + } + if (visState && visState.type === 'pie') { + return { + ...doc, + attributes: { + ...doc.attributes, + visState: JSON.stringify({ + ...visState, + params: { + ...visState.params, + palette: { + type: 'palette', + name: 'kibana_palette', + }, + }, + }), + }, + }; + } + } + return doc; +}; + export const visualizationSavedObjectTypeMigrations = { /** * We need to have this migration twice, once with a version prior to 7.0.0 once with a version @@ -790,4 +823,5 @@ export const visualizationSavedObjectTypeMigrations = { '7.8.0': flow(migrateTsvbDefaultColorPalettes), '7.9.3': flow(migrateMatchAllQuery), '7.10.0': flow(migrateFilterRatioQuery, removeTSVBSearchSource), + '7.12.0': flow(migrateVislibPie), }; From ca1ffb1c7c727afb43be45d434026f708d1bbc06 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 1 Dec 2020 18:12:36 +0200 Subject: [PATCH 018/111] Add unit tests (wip) and a small refactoring --- .../editor/components/palette_picker.test.tsx | 67 +++++ .../editor/components/palette_picker.tsx | 14 +- .../public/editor/components/pie.tsx | 2 + .../components/truncate_labels.test.tsx | 61 +++++ .../editor/components/truncate_labels.tsx | 3 +- .../public/pie_component.test.tsx | 248 ++++++++++++++++++ .../vis_type_pie/public/pie_component.tsx | 97 ++----- .../vis_type_pie/public/pie_renderer.tsx | 2 + .../vis_type_pie/public/temp/color_picker.tsx | 2 +- .../public/utils/filter_helpers.test.ts | 176 +++++++++++++ .../public/utils/filter_helpers.ts | 77 ++++++ .../public/utils/get_color_picker.test.tsx | 235 +++++++++++++++++ .../public/utils/get_legend_actions.tsx | 2 +- .../vis_type_pie/public/utils/index.ts | 1 + 14 files changed, 905 insertions(+), 82 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx create mode 100644 src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx create mode 100644 src/plugins/vis_type_pie/public/pie_component.test.tsx create mode 100644 src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts create mode 100644 src/plugins/vis_type_pie/public/utils/filter_helpers.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx new file mode 100644 index 00000000000000..0574a478776196 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx @@ -0,0 +1,67 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { mountWithIntl } from '@kbn/test/jest'; +import { ReactWrapper } from 'enzyme'; +import { PalettePicker, PalettePickerProps } from './palette_picker'; +import { findTestSubject } from '@elastic/eui/lib/test'; +import { chartPluginMock } from '../../../../charts/public/mocks'; +import { EuiColorPalettePicker } from '@elastic/eui'; + +describe('PalettePicker', function () { + let props: PalettePickerProps<'palette'>; + let component: ReactWrapper>; + + beforeAll(() => { + props = { + palettes: chartPluginMock.createPaletteRegistry(), + paramName: 'palette', + activePalette: { + type: 'palette', + name: 'kibana_palette', + }, + setPalette: jest.fn(), + }; + }); + + it('renders the EuiPalettePicker', () => { + component = mountWithIntl(); + expect(component.find(EuiColorPalettePicker).length).toBe(1); + }); + + it('renders the default palette if not activePalette is given', function () { + const { activePalette, ...newProps } = props; + component = mountWithIntl(); + const palettePicker = component.find(EuiColorPalettePicker); + expect(palettePicker.props().valueOfSelected).toBe('default'); + }); + + it('renders the activePalette palette if given', function () { + component = mountWithIntl(); + const palettePicker = component.find(EuiColorPalettePicker); + expect(palettePicker.props().valueOfSelected).toBe('kibana_palette'); + }); + + it('should set the new palette', function () { + component = mountWithIntl(); + const input = findTestSubject(component, 'piePalettePicker'); + input.simulate('change', { target: { value: 'temperature' } }); + expect(props.setPalette).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx index 02ac494e50ced0..144288db6342e2 100644 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx @@ -18,25 +18,24 @@ */ import React from 'react'; -import { PaletteOutput } from 'src/plugins/charts/public'; +import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; import { EuiColorPalettePicker } from '@elastic/eui'; import { EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { getColorsService } from '../../services'; -interface PalettePickerProps { +export interface PalettePickerProps { 'data-test-subj'?: string; activePalette?: PaletteOutput; + palettes: PaletteRegistry; paramName: ParamName; setPalette: (paramName: ParamName, value: PaletteOutput) => void; - disabled?: boolean; } export function PalettePicker({ activePalette, + palettes, paramName, setPalette, - disabled, }: PalettePickerProps) { return ( ({ })} > !internal) .map(({ id, title, getColors }) => { diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 64897b1af8c34c..9d4d671560bfb2 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -28,6 +28,7 @@ import { PalettePicker } from './palette_picker'; import { BasicOptions, SwitchOption, SelectOption } from '../../../../charts/public'; import { PieVisParams } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; +import { getColorsService } from '../../services'; function PieOptions(props: VisOptionsProps) { const { stateParams, setValue } = props; @@ -66,6 +67,7 @@ function PieOptions(props: VisOptionsProps) { setValue={setValue} /> ; + + beforeAll(() => { + props = { + disabled: false, + value: 20, + setValue: jest.fn(), + }; + }); + + it('renders an input type number', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'pieLabelTruncateInput').length).toBe(1); + }); + + it('renders the value on the input number', function () { + component = mountWithIntl(); + const input = findTestSubject(component, 'pieLabelTruncateInput'); + expect(input.props().value).toBe(20); + }); + + it('disables the input if disabled prop is given', function () { + const newProps = { ...props, disabled: true }; + component = mountWithIntl(); + const input = findTestSubject(component, 'pieLabelTruncateInput'); + expect(input.props().disabled).toBe(true); + }); + + it('should set the new value', function () { + component = mountWithIntl(); + const input = findTestSubject(component, 'pieLabelTruncateInput'); + input.simulate('change', { target: { value: 100 } }); + expect(props.setValue).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx index 514615b3af2aa3..df6af3289a10d7 100644 --- a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx @@ -21,7 +21,7 @@ import React, { ChangeEvent } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiFieldNumber } from '@elastic/eui'; -interface TruncateLabelsOptionProps { +export interface TruncateLabelsOptionProps { disabled?: boolean; value?: number | null; setValue: (paramName: 'truncate', value: null | number) => void; @@ -40,6 +40,7 @@ function TruncateLabelsOption({ disabled, value = null, setValue }: TruncateLabe display="rowCompressed" > ({ + getColorsService: jest.fn().mockReturnValue({ + get: jest.fn(), + getAll: jest.fn(), + }), + getFormatService: jest.fn().mockReturnValue({ + deserialize: jest.fn(), + getAll: jest.fn(), + }), +})); + +jest.mock('@elastic/charts', () => { + const original = jest.requireActual('@elastic/charts'); + + return { + ...original, + getSpecId: jest.fn(() => {}), + }; +}); + +const chartsThemeService = chartPluginMock.createSetupContract().theme; + +const visParams = ({ + addLegend: true, + addTooltip: true, + isDonut: true, + labels: { + position: 'default', + show: true, + truncate: 100, + values: true, + valuesFormat: 'percent', + }, + legendPosition: 'right', + nestedLegend: false, + palette: { + name: 'default', + type: 'palette', + }, + type: 'pie', + dimensions: { + metric: { + accessor: 1, + format: { + id: 'number', + }, + params: {}, + label: 'Count', + aggType: 'count', + }, + buckets: [ + { + accessor: 0, + format: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + params: {}, + label: 'Carrier: Descending', + aggType: 'terms', + }, + ], + }, +} as unknown) as PieVisParams; + +const visData = { + type: 'datatable', + rows: [ + { + 'col-0-2': 'Logstash Airways', + 'col-1-1': 709, + }, + { + 'col-0-2': 'JetBeats', + 'col-1-1': 692, + }, + { + 'col-0-2': 'ES-Air', + 'col-1-1': 662, + }, + { + 'col-0-2': 'Kibana Airlines', + 'col-1-1': 647, + }, + ], + columns: [ + { + id: 'col-0-2', + name: 'Carrier: Descending', + meta: { + type: 'string', + field: 'Carrier', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + }, + { + id: 'col-1-1', + name: 'Count', + meta: { + type: 'number', + index: 'kibana_sample_data_flights', + params: { + id: 'number', + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '1', + enabled: true, + type: 'count', + params: {}, + schema: 'metric', + }, + }, + }, + ], +} as Datatable; + +const mockState = new Map(); +const uiState = { + get: jest + .fn() + .mockImplementation((key, fallback) => (mockState.has(key) ? mockState.get(key) : fallback)), + set: jest.fn().mockImplementation((key, value) => mockState.set(key, value)), + emit: jest.fn(), + setSilent: jest.fn(), +} as any; + +describe('PieComponent', function () { + let wrapperProps: PieComponentProps; + + beforeAll(() => { + wrapperProps = { + chartsThemeService, + visParams, + visData, + uiState, + fireEvent: jest.fn(), + renderComplete: jest.fn(), + }; + }); + + it('renders the legend on the correct position', () => { + const component = shallow(); + expect(component.find(Settings).prop('legendPosition')).toEqual('right'); + }); + + it('renders the legend toggle component', () => { + const component = mount(); + expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1); + }); + + it('hides the legend if the legend toggle is clicked', () => { + const component = mount(); + const toggle = findTestSubject(component, 'vislibToggleLegend'); + toggle.simulate('click'); + expect(component.find(Settings).prop('showLegend')).toEqual(false); + }); + + it('defaults on showing the legend for the inner cicle', () => { + const component = shallow(); + expect(component.find(Settings).prop('legendMaxDepth')).toBe(1); + }); + + it('shows the nested legend when the user requests it', () => { + const newParams = { ...visParams, nestedLegend: true }; + const newProps = { ...wrapperProps, visParams: newParams }; + const component = shallow(); + expect(component.find(Settings).prop('legendMaxDepth')).toBeUndefined(); + }); + + it('defaults on displaying the tooltip', () => { + const component = shallow(); + expect(component.find(Settings).prop('tooltip')).toStrictEqual({ type: TooltipType.Follow }); + }); + + it('doesnt show the tooltip when the user requests it', () => { + const newParams = { ...visParams, addTooltip: false }; + const newProps = { ...wrapperProps, visParams: newParams }; + const component = shallow(); + expect(component.find(Settings).prop('tooltip')).toStrictEqual({ type: TooltipType.None }); + }); + + it('calls filter callback', () => { + const component = shallow(); + component.find(Settings).first().prop('onElementClick')!([ + [[{ groupByRollup: 6, value: 6 }], {} as SeriesIdentifier], + ]); + expect(wrapperProps.fireEvent).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index ab1a9ae75fe9b8..6fa6604bc36731 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -33,7 +33,6 @@ import { Partition, PartitionConfig, PartitionLayout, - PartitionFillLabel, RecursivePartial, Position, Settings, @@ -44,18 +43,25 @@ import { } from '@elastic/charts'; import { keys } from '@elastic/eui'; -// import { -// getFilterFromChartClickEventFn, -// getFilterFromSeriesFn, -// LegendToggle, -// ClickTriggerEvent, -// } from '../../charts/public'; +import { + // getFilterFromChartClickEventFn, + // getFilterFromSeriesFn, + // LegendToggle, + // ClickTriggerEvent, + ChartsPluginSetup, +} from '../../charts/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; -import { ValueClickContext } from '../../embeddable/public'; - import { PieVisParams, BucketColumns, LabelPositions, ValueFormats } from './types'; -import { getThemeService, getFormatService, getDataActions } from './services'; -import { getColorPicker, getLayers, getLegendActions, ClickTriggerEvent } from './utils'; +import { getFormatService } from './services'; +import { + getColorPicker, + getLayers, + getLegendActions, + ClickTriggerEvent, + canFilter, + getFilterClickData, + getFilterEventData, +} from './utils'; import { LegendToggle } from './temp'; import './chart.scss'; @@ -66,13 +72,14 @@ export interface PieComponentProps { uiState: IInterpreterRenderHandlers['uiState']; fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; + chartsThemeService: ChartsPluginSetup['theme']; } export type PieComponentType = typeof PieComponent; const PieComponent = (props: PieComponentProps) => { - const chartTheme = getThemeService().useChartsTheme(); - const chartBaseTheme = getThemeService().useChartsBaseTheme(); + const chartTheme = props.chartsThemeService.useChartsTheme(); + const chartBaseTheme = props.chartsThemeService.useChartsBaseTheme(); const [showLegend, setShowLegend] = useState(true); const onRenderChange = useCallback( @@ -84,56 +91,21 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - // move it to utils const handleFilterClick = useCallback( (clickedLayers: LayerValue[], bucketColumns: BucketColumns[], visData: Datatable): void => { - const data: ValueClickContext['data']['data'] = []; - const matchingIndex = visData.rows.findIndex((row) => - clickedLayers.every((layer, index) => { - const columnId = bucketColumns[index].id; - return row[columnId] === layer.groupByRollup; - }) - ); - - data.push( - ...clickedLayers.map((clickedLayer, index) => ({ - column: visData.columns.findIndex((col) => col.id === bucketColumns[index].id), - row: matchingIndex, - value: clickedLayer.groupByRollup, - table: visData, - })) - ); - + const data = getFilterClickData(clickedLayers, bucketColumns, visData); const event = { name: 'filterBucket', data: { data }, }; - props.fireEvent(event); }, [props] ); - const getFilterEventData = useCallback( + const getFilterEventDataCallback = useCallback( (visData: Datatable) => (series: SeriesIdentifier): ClickTriggerEvent | null => { - // console.log(series.key); - const data = visData.columns.reduce( - (acc, { id }, column) => { - const value = series.key; - const row = visData.rows.findIndex((r) => r[id] === value); - if (row > -1) { - acc.push({ - table: visData, - column, - row, - value, - }); - } - - return acc; - }, - [] - ); + const data = getFilterEventData(visData, series); return { name: 'filterBucket', @@ -159,14 +131,6 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - const canFilter = async (event: ClickTriggerEvent | null): Promise => { - if (!event) { - return false; - } - const filters = await getDataActions().createFiltersFromValueClickAction(event.data); - return Boolean(filters.length); - }; - const toggleLegend = useCallback(() => { setShowLegend((value) => { const newValue = !value; @@ -203,17 +167,7 @@ const PieComponent = (props: PieComponentProps) => { return Number.EPSILON; } - const fillLabel: Partial = { - textInvertible: true, - valueFont: { - fontWeight: 700, - }, - }; - - if (!visParams.labels.values) { - fillLabel.valueFormatter = () => ''; - } - + // move it to get_config file const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, @@ -268,6 +222,7 @@ const PieComponent = (props: PieComponentProps) => { const palette = visParams.palette.name; + // useCallback const layers = getLayers( layersColumns, visParams, @@ -310,7 +265,7 @@ const PieComponent = (props: PieComponentProps) => { }} legendAction={getLegendActions( canFilter, - getFilterEventData(visData), + getFilterEventDataCallback(visData), handleFilterAction, visParams )} diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index baaec8902c5b29..8ce899dfc3064e 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -25,6 +25,7 @@ import { VisualizationContainer } from '../../visualizations/public'; // import { SplitChartWarning } from './components'; import { RenderValue, vislibPieName } from './pie_fn'; +import { getThemeService } from './services'; const PieComponent = lazy(() => import('./pie_component')); @@ -49,6 +50,7 @@ export const pieVisRenderer: ExpressionRenderDefinition = { {/* {isSplitChart && } */} ( -
+
{ + it('returns the correct filter data for the specific layer', () => { + const clickedLayers = [ + { + groupByRollup: 'Logstash Airways', + value: 729, + }, + ]; + const data = getFilterClickData(clickedLayers, bucketColumns, visData); + expect(data.length).toEqual(clickedLayers.length); + expect(data[0].value).toEqual('Logstash Airways'); + expect(data[0].row).toEqual(0); + expect(data[0].column).toEqual(0); + }); + + it('changes if the user clicks on another layer', () => { + const clickedLayers = [ + { + groupByRollup: 'ES-Air', + value: 572, + }, + ]; + const data = getFilterClickData(clickedLayers, bucketColumns, visData); + expect(data.length).toEqual(clickedLayers.length); + expect(data[0].value).toEqual('ES-Air'); + expect(data[0].row).toEqual(2); + expect(data[0].column).toEqual(0); + }); +}); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts new file mode 100644 index 00000000000000..951032db7d9c26 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -0,0 +1,77 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { LayerValue, SeriesIdentifier } from '@elastic/charts'; +import { Datatable } from '../../../expressions/public'; +import { ValueClickContext } from '../../../embeddable/public'; +import { ClickTriggerEvent } from './get_legend_actions'; +import { getDataActions } from '../services'; +import { BucketColumns } from '../types'; + +export const canFilter = async (event: ClickTriggerEvent | null): Promise => { + if (!event) { + return false; + } + const filters = await getDataActions().createFiltersFromValueClickAction(event.data); + return Boolean(filters.length); +}; + +export const getFilterClickData = ( + clickedLayers: LayerValue[], + bucketColumns: BucketColumns[], + visData: Datatable +): ValueClickContext['data']['data'] => { + const data: ValueClickContext['data']['data'] = []; + const matchingIndex = visData.rows.findIndex((row) => + clickedLayers.every((layer, index) => { + const columnId = bucketColumns[index].id; + return row[columnId] === layer.groupByRollup; + }) + ); + + data.push( + ...clickedLayers.map((clickedLayer, index) => ({ + column: visData.columns.findIndex((col) => col.id === bucketColumns[index].id), + row: matchingIndex, + value: clickedLayer.groupByRollup, + table: visData, + })) + ); + + return data; +}; + +export const getFilterEventData = ( + visData: Datatable, + series: SeriesIdentifier +): ValueClickContext['data']['data'] => { + return visData.columns.reduce((acc, { id }, column) => { + const value = series.key; + const row = visData.rows.findIndex((r) => r[id] === value); + if (row > -1) { + acc.push({ + table: visData, + column, + row, + value, + }); + } + + return acc; + }, []); +}; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx new file mode 100644 index 00000000000000..e9b000cdcb23f9 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -0,0 +1,235 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { LegendColorPickerProps } from '@elastic/charts'; +import { EuiWrappingPopover } from '@elastic/eui'; +import { mount } from 'enzyme'; +import { ComponentType, ReactWrapper } from 'enzyme'; +import { findTestSubject } from '@elastic/eui/lib/test'; +import { BucketColumns } from '../types'; +import { getColorPicker } from './get_color_picker'; +import { ColorPicker } from '../temp'; + +const layersColumns = [ + { + id: 'col-0-2', + name: 'Carrier: Descending', + meta: { + type: 'string', + field: 'Carrier', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + format: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + }, + { + id: 'col-2-3', + name: 'Cancelled: Descending', + meta: { + type: 'boolean', + field: 'Cancelled', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '3', + enabled: true, + type: 'terms', + params: { + field: 'Cancelled', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + format: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + }, +] as Array>; + +const data = [ + { + 'col-0-2': 'Logstash Airways', + 'col-2-3': 0, + 'col-1-1': 726, + 'col-3-1': 624, + }, + { + 'col-0-2': 'Logstash Airways', + 'col-2-3': 1, + 'col-1-1': 726, + 'col-3-1': 102, + }, + { + 'col-0-2': 'JetBeats', + 'col-2-3': 0, + 'col-1-1': 703, + 'col-3-1': 602, + }, + { + 'col-0-2': 'JetBeats', + 'col-2-3': 1, + 'col-1-1': 703, + 'col-3-1': 101, + }, + { + 'col-0-2': 'ES-Air', + 'col-2-3': 0, + 'col-1-1': 667, + 'col-3-1': 601, + }, + { + 'col-0-2': 'ES-Air', + 'col-2-3': 1, + 'col-1-1': 667, + 'col-3-1': 66, + }, + { + 'col-0-2': 'Kibana Airlines', + 'col-2-3': 0, + 'col-1-1': 658, + 'col-3-1': 588, + }, + { + 'col-0-2': 'Kibana Airlines', + 'col-2-3': 1, + 'col-1-1': 658, + 'col-3-1': 70, + }, +]; + +jest.mock('@elastic/charts', () => { + const original = jest.requireActual('@elastic/charts'); + + return { + ...original, + getSpecId: jest.fn(() => {}), + }; +}); + +describe('getColorPicker', function () { + let wrapperProps: LegendColorPickerProps; + const Component: ComponentType = getColorPicker( + 'left', + jest.fn(), + layersColumns, + 'default', + data + ); + let wrapper: ReactWrapper; + + beforeAll(() => { + wrapperProps = { + color: 'rgb(109, 204, 177)', + onClose: jest.fn(), + onChange: jest.fn(), + anchor: document.createElement('div'), + seriesIdentifier: { + key: 'Logstash Airways', + specId: 'pie', + }, + }; + }); + + it('renders the color picker for default palette and inner layer', () => { + wrapper = mount(); + expect(findTestSubject(wrapper, 'visColorPicker').length).toBe(1); + }); + + it('renders the picker on the correct position', () => { + wrapper = mount(); + expect(wrapper.find(EuiWrappingPopover).prop('anchorPosition')).toEqual('rightCenter'); + }); + + it('converts the color to the right hex and passes it to the color picker', () => { + wrapper = mount(); + expect(wrapper.find(ColorPicker).prop('color')).toEqual('#6DCCB1'); + }); + + it('doesnt render the picker for default palette and not inner layer', () => { + const newProps = { ...wrapperProps, seriesIdentifier: { key: '1', specId: 'pie' } }; + wrapper = mount(); + expect(wrapper).toEqual({}); + }); + + it('renders the picker for kibana palette and not inner layer', () => { + const LegacyPaletteComponent: ComponentType = getColorPicker( + 'left', + jest.fn(), + layersColumns, + 'kibana_palette', + data + ); + const newProps = { ...wrapperProps, seriesIdentifier: { key: '1', specId: 'pie' } }; + wrapper = mount(); + expect(findTestSubject(wrapper, 'visColorPicker').length).toBe(1); + }); +}); diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 50073ed37cf715..7beb4fcaa5badc 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -53,7 +53,7 @@ export const getLegendActions = ( let formattedTitle = ''; if (visParams.dimensions.buckets) { - const column = visParams.dimensions?.buckets.find( + const column = visParams.dimensions.buckets.find( (bucket) => bucket.accessor === filterData.data.data[0].column ); formattedTitle = getFormatService().deserialize(column?.format).convert(series.key) ?? ''; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 862c72f849d775..8721888918a880 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -20,3 +20,4 @@ export { getLayers } from './get_layers'; export { getColorPicker } from './get_color_picker'; export { getLegendActions, ClickTriggerEvent } from './get_legend_actions'; +export { canFilter, getFilterClickData, getFilterEventData } from './filter_helpers'; From 8390ff78cda7fa21396aa776b0de507d244cb2ff Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 2 Dec 2020 14:50:06 +0200 Subject: [PATCH 019/111] Add unit tests and move some things to utils, useMemo and useCallback where it should --- src/plugins/vis_type_pie/public/mocks.ts | 340 ++++++++++++++++++ .../public/pie_component.test.tsx | 131 +------ .../vis_type_pie/public/pie_component.tsx | 103 ++---- .../public/utils/filter_helpers.test.ts | 157 ++------ .../public/utils/filter_helpers.ts | 3 +- .../public/utils/get_color_picker.test.tsx | 151 +------- .../public/utils/get_color_picker.tsx | 8 +- .../public/utils/get_columns.test.ts | 189 ++++++++++ .../vis_type_pie/public/utils/get_columns.ts | 42 +++ .../vis_type_pie/public/utils/get_config.ts | 53 +++ .../vis_type_pie/public/utils/index.ts | 2 + 11 files changed, 704 insertions(+), 475 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/mocks.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_columns.test.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_columns.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_config.ts diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts new file mode 100644 index 00000000000000..9e46e05b0857a4 --- /dev/null +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -0,0 +1,340 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Datatable } from '../../expressions/public'; +import { BucketColumns, PieVisParams, LabelPositions, ValueFormats } from './types'; + +export const createMockBucketColumns = (): BucketColumns[] => { + return [ + { + id: 'col-0-2', + name: 'Carrier: Descending', + meta: { + type: 'string', + field: 'Carrier', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + format: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + }, + { + id: 'col-2-3', + name: 'Cancelled: Descending', + meta: { + type: 'boolean', + field: 'Cancelled', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '3', + enabled: true, + type: 'terms', + params: { + field: 'Cancelled', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + format: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + }, + ]; +}; + +export const createMockVisData = (): Datatable => { + return { + type: 'datatable', + rows: [ + { + 'col-0-2': 'Logstash Airways', + 'col-2-3': 0, + 'col-1-1': 797, + 'col-3-1': 689, + }, + { + 'col-0-2': 'Logstash Airways', + 'col-2-3': 1, + 'col-1-1': 797, + 'col-3-1': 108, + }, + { + 'col-0-2': 'JetBeats', + 'col-2-3': 0, + 'col-1-1': 766, + 'col-3-1': 654, + }, + { + 'col-0-2': 'JetBeats', + 'col-2-3': 1, + 'col-1-1': 766, + 'col-3-1': 112, + }, + { + 'col-0-2': 'ES-Air', + 'col-2-3': 0, + 'col-1-1': 744, + 'col-3-1': 665, + }, + { + 'col-0-2': 'ES-Air', + 'col-2-3': 1, + 'col-1-1': 744, + 'col-3-1': 79, + }, + { + 'col-0-2': 'Kibana Airlines', + 'col-2-3': 0, + 'col-1-1': 731, + 'col-3-1': 655, + }, + { + 'col-0-2': 'Kibana Airlines', + 'col-2-3': 1, + 'col-1-1': 731, + 'col-3-1': 76, + }, + ], + columns: [ + { + id: 'col-0-2', + name: 'Carrier: Descending', + meta: { + type: 'string', + field: 'Carrier', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + }, + { + id: 'col-1-1', + name: 'Count', + meta: { + type: 'number', + index: 'kibana_sample_data_flights', + params: { + id: 'number', + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '1', + enabled: true, + type: 'count', + params: {}, + schema: 'metric', + }, + }, + }, + { + id: 'col-2-3', + name: 'Cancelled: Descending', + meta: { + type: 'boolean', + field: 'Cancelled', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '3', + enabled: true, + type: 'terms', + params: { + field: 'Cancelled', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + }, + }, + }, + { + id: 'col-3-1', + name: 'Count', + meta: { + type: 'number', + index: 'kibana_sample_data_flights', + params: { + id: 'number', + }, + source: 'esaggs', + sourceParams: { + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + id: '1', + enabled: true, + type: 'count', + params: {}, + schema: 'metric', + }, + }, + }, + ], + }; +}; + +export const createMockPieParams = (): PieVisParams => { + return ({ + addLegend: true, + addTooltip: true, + isDonut: true, + labels: { + position: LabelPositions.DEFAULT, + show: true, + truncate: 100, + values: true, + valuesFormat: ValueFormats.PERCENT, + }, + legendPosition: 'right', + nestedLegend: false, + palette: { + name: 'default', + type: 'palette', + }, + type: 'pie', + dimensions: { + metric: { + accessor: 1, + format: { + id: 'number', + }, + params: {}, + label: 'Count', + aggType: 'count', + }, + buckets: [ + { + accessor: 0, + format: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + label: 'Carrier: Descending', + aggType: 'terms', + }, + { + accessor: 2, + format: { + id: 'terms', + params: { + id: 'boolean', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + label: 'Cancelled: Descending', + aggType: 'terms', + }, + ], + }, + } as unknown) as PieVisParams; +}; diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index 45a98b9551032f..a3eab40f7d88cb 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -18,12 +18,11 @@ */ import React from 'react'; import { Settings, TooltipType, SeriesIdentifier } from '@elastic/charts'; -import { Datatable } from '../../expressions/public'; import { chartPluginMock } from '../../charts/public/mocks'; import { shallow, mount } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { PieVisParams } from './types'; import PieComponent, { PieComponentProps } from './pie_component'; +import { createMockPieParams, createMockVisData } from './mocks'; jest.mock('./services', () => ({ getColorsService: jest.fn().mockReturnValue({ @@ -46,132 +45,8 @@ jest.mock('@elastic/charts', () => { }); const chartsThemeService = chartPluginMock.createSetupContract().theme; - -const visParams = ({ - addLegend: true, - addTooltip: true, - isDonut: true, - labels: { - position: 'default', - show: true, - truncate: 100, - values: true, - valuesFormat: 'percent', - }, - legendPosition: 'right', - nestedLegend: false, - palette: { - name: 'default', - type: 'palette', - }, - type: 'pie', - dimensions: { - metric: { - accessor: 1, - format: { - id: 'number', - }, - params: {}, - label: 'Count', - aggType: 'count', - }, - buckets: [ - { - accessor: 0, - format: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - params: {}, - label: 'Carrier: Descending', - aggType: 'terms', - }, - ], - }, -} as unknown) as PieVisParams; - -const visData = { - type: 'datatable', - rows: [ - { - 'col-0-2': 'Logstash Airways', - 'col-1-1': 709, - }, - { - 'col-0-2': 'JetBeats', - 'col-1-1': 692, - }, - { - 'col-0-2': 'ES-Air', - 'col-1-1': 662, - }, - { - 'col-0-2': 'Kibana Airlines', - 'col-1-1': 647, - }, - ], - columns: [ - { - id: 'col-0-2', - name: 'Carrier: Descending', - meta: { - type: 'string', - field: 'Carrier', - index: 'kibana_sample_data_flights', - params: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '2', - enabled: true, - type: 'terms', - params: { - field: 'Carrier', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - }, - }, - }, - { - id: 'col-1-1', - name: 'Count', - meta: { - type: 'number', - index: 'kibana_sample_data_flights', - params: { - id: 'number', - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '1', - enabled: true, - type: 'count', - params: {}, - schema: 'metric', - }, - }, - }, - ], -} as Datatable; +const visParams = createMockPieParams(); +const visData = createMockVisData(); const mockState = new Map(); const uiState = { diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 6fa6604bc36731..cfe75dd4eca48f 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -31,9 +31,6 @@ import { Datum, LayerValue, Partition, - PartitionConfig, - PartitionLayout, - RecursivePartial, Position, Settings, RenderChangeListener, @@ -51,7 +48,7 @@ import { ChartsPluginSetup, } from '../../charts/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; -import { PieVisParams, BucketColumns, LabelPositions, ValueFormats } from './types'; +import { PieVisParams, BucketColumns, ValueFormats } from './types'; import { getFormatService } from './services'; import { getColorPicker, @@ -61,6 +58,8 @@ import { canFilter, getFilterClickData, getFilterEventData, + getConfig, + getColumns, } from './utils'; import { LegendToggle } from './temp'; @@ -75,8 +74,6 @@ export interface PieComponentProps { chartsThemeService: ChartsPluginSetup['theme']; } -export type PieComponentType = typeof PieComponent; - const PieComponent = (props: PieComponentProps) => { const chartTheme = props.chartsThemeService.useChartsTheme(); const chartBaseTheme = props.chartsThemeService.useChartsBaseTheme(); @@ -91,8 +88,13 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - const handleFilterClick = useCallback( - (clickedLayers: LayerValue[], bucketColumns: BucketColumns[], visData: Datatable): void => { + // handles slice click event + const handleSliceClick = useCallback( + ( + clickedLayers: LayerValue[], + bucketColumns: Array>, + visData: Datatable + ): void => { const data = getFilterClickData(clickedLayers, bucketColumns, visData); const event = { name: 'filterBucket', @@ -103,7 +105,8 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - const getFilterEventDataCallback = useCallback( + // handles legend action event data + const getLegendActionEventData = useCallback( (visData: Datatable) => (series: SeriesIdentifier): ClickTriggerEvent | null => { const data = getFilterEventData(visData, series); @@ -118,7 +121,7 @@ const PieComponent = (props: PieComponentProps) => { [] ); - const handleFilterAction = useCallback( + const handleLegendAction = useCallback( (event: ClickTriggerEvent, negate = false) => { props.fireEvent({ ...event, @@ -144,7 +147,6 @@ const PieComponent = (props: PieComponentProps) => { if ((event as KeyboardEvent).key && (event as KeyboardEvent).key !== keys.ENTER) { return; } - const colors = props.uiState?.get('vis.colors') || {}; if (colors[seriesLabel] === newColor || !newColor) { delete colors[seriesLabel]; @@ -167,33 +169,7 @@ const PieComponent = (props: PieComponentProps) => { return Number.EPSILON; } - // move it to get_config file - const config: RecursivePartial = { - partitionLayout: PartitionLayout.sunburst, - fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, - outerSizeRatio: 1, - specialFirstInnermostSector: true, - clockwiseSectors: false, - minFontSize: 10, - maxFontSize: 16, - linkLabel: { - maxCount: 5, - fontSize: 11, - textColor: chartTheme.axes?.axisTitle?.fill, - maxTextLength: visParams.labels.truncate ?? undefined, - }, - sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill, - sectorLineWidth: 1.5, - circlePadding: 4, - emptySizeRatio: visParams.isDonut ? 0.3 : 0, - }; - if (!visParams.labels.show) { - // Force all labels to be linked, then prevent links from showing - config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; - } - if (visParams.labels.position === LabelPositions.INSIDE) { - config.linkLabel = { maxCount: 0 }; - } + // formatters const metricFieldFormatter = getFormatService().deserialize(visParams.dimensions.metric.format); const percentFormatter = getFormatService().deserialize({ id: 'percent', @@ -202,39 +178,26 @@ const PieComponent = (props: PieComponentProps) => { }, }); - let layersColumns: Array> = []; - const bucketColumns: BucketColumns[] = []; - let metricColumn: DatatableColumn; - if (visParams.dimensions.buckets) { - visParams.dimensions.buckets.forEach((b) => { - bucketColumns.push({ ...visData.columns[b.accessor], format: b.format }); - layersColumns = [...bucketColumns]; - }); - const lastBucketId = layersColumns[layersColumns.length - 1].id; - const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); - metricColumn = visData.columns[matchingIndex + 1]; - } else { - metricColumn = visData.columns[0]; - layersColumns.push({ - name: metricColumn.name, - }); - } - - const palette = visParams.palette.name; - - // useCallback - const layers = getLayers( - layersColumns, + const { bucketColumns, metricColumn } = useMemo(() => getColumns(visParams, visData), [ + visData, visParams, - props.uiState?.get('vis.colors', {}), - visData.rows.length, - palette - ); + ]); + const layers = useMemo( + () => + getLayers( + bucketColumns, + visParams, + props.uiState?.get('vis.colors', {}), + visData.rows.length, + visParams.palette.name + ), + [bucketColumns, props.uiState, visData.rows.length, visParams] + ); + const config = useMemo(() => getConfig(visParams, chartTheme), [chartTheme, visParams]); const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, }; - const legendPosition = useMemo(() => visParams.legendPosition ?? Position.Right, [ visParams.legendPosition, ]); @@ -255,18 +218,18 @@ const PieComponent = (props: PieComponentProps) => { legendColorPicker={getColorPicker( legendPosition, setColor, - layersColumns, + bucketColumns, visParams.palette.name, visData.rows )} tooltip={tooltip} onElementClick={(args) => { - handleFilterClick(args[0][0] as LayerValue[], bucketColumns, visData); + handleSliceClick(args[0][0] as LayerValue[], bucketColumns, visData); }} legendAction={getLegendActions( canFilter, - getFilterEventDataCallback(visData), - handleFilterAction, + getLegendActionEventData(visData), + handleLegendAction, visParams )} theme={chartTheme} diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index fd935f68a8ab14..03f7c8339fc45c 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -16,134 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import { Datatable } from '../../../expressions/public'; -import { getFilterClickData } from './filter_helpers'; -import { BucketColumns } from '../types'; +import { getFilterClickData, getFilterEventData } from './filter_helpers'; +import { createMockBucketColumns, createMockVisData } from '../mocks'; -const bucketColumns = [ - { - id: 'col-0-2', - name: 'Carrier: Descending', - meta: { - type: 'string', - field: 'Carrier', - index: 'kibana_sample_data_flights', - params: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '2', - enabled: true, - type: 'terms', - params: { - field: 'Carrier', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - }, - }, - format: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - }, -] as BucketColumns[]; - -const visData = { - type: 'datatable', - rows: [ - { - 'col-0-2': 'Logstash Airways', - 'col-1-1': 729, - }, - { - 'col-0-2': 'JetBeats', - 'col-1-1': 706, - }, - { - 'col-0-2': 'ES-Air', - 'col-1-1': 672, - }, - { - 'col-0-2': 'Kibana Airlines', - 'col-1-1': 662, - }, - ], - columns: [ - { - id: 'col-0-2', - name: 'Carrier: Descending', - meta: { - type: 'string', - field: 'Carrier', - index: 'kibana_sample_data_flights', - params: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '2', - enabled: true, - type: 'terms', - params: { - field: 'Carrier', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - }, - }, - }, - { - id: 'col-1-1', - name: 'Count', - meta: { - type: 'number', - index: 'kibana_sample_data_flights', - params: { - id: 'number', - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '1', - enabled: true, - type: 'count', - params: {}, - schema: 'metric', - }, - }, - }, - ], -} as Datatable; +const bucketColumns = createMockBucketColumns(); +const visData = createMockVisData(); describe('getFilterClickData', () => { it('returns the correct filter data for the specific layer', () => { @@ -160,7 +37,7 @@ describe('getFilterClickData', () => { expect(data[0].column).toEqual(0); }); - it('changes if the user clicks on another layer', () => { + it('changes the filter if the user clicks on another layer', () => { const clickedLayers = [ { groupByRollup: 'ES-Air', @@ -170,6 +47,30 @@ describe('getFilterClickData', () => { const data = getFilterClickData(clickedLayers, bucketColumns, visData); expect(data.length).toEqual(clickedLayers.length); expect(data[0].value).toEqual('ES-Air'); + expect(data[0].row).toEqual(4); + expect(data[0].column).toEqual(0); + }); +}); + +describe('getFilterEventData', () => { + it('returns the correct filter data for the specific series', () => { + const series = { + key: 'Kibana Airlines', + specId: 'pie', + }; + const data = getFilterEventData(visData, series); + expect(data[0].value).toEqual('Kibana Airlines'); + expect(data[0].row).toEqual(6); + expect(data[0].column).toEqual(0); + }); + + it('changes the filter if the user clicks on another series', () => { + const series = { + key: 'JetBeats', + specId: 'pie', + }; + const data = getFilterEventData(visData, series); + expect(data[0].value).toEqual('JetBeats'); expect(data[0].row).toEqual(2); expect(data[0].column).toEqual(0); }); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 951032db7d9c26..4348857b12eaa0 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -33,13 +33,14 @@ export const canFilter = async (event: ClickTriggerEvent | null): Promise>, visData: Datatable ): ValueClickContext['data']['data'] => { const data: ValueClickContext['data']['data'] = []; const matchingIndex = visData.rows.findIndex((row) => clickedLayers.every((layer, index) => { const columnId = bucketColumns[index].id; + if (!columnId) return; return row[columnId] === layer.groupByRollup; }) ); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index e9b000cdcb23f9..3f2e57aa113f66 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -22,149 +22,12 @@ import { EuiWrappingPopover } from '@elastic/eui'; import { mount } from 'enzyme'; import { ComponentType, ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { BucketColumns } from '../types'; import { getColorPicker } from './get_color_picker'; import { ColorPicker } from '../temp'; +import { createMockBucketColumns, createMockVisData } from '../mocks'; -const layersColumns = [ - { - id: 'col-0-2', - name: 'Carrier: Descending', - meta: { - type: 'string', - field: 'Carrier', - index: 'kibana_sample_data_flights', - params: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '2', - enabled: true, - type: 'terms', - params: { - field: 'Carrier', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - }, - }, - format: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - }, - { - id: 'col-2-3', - name: 'Cancelled: Descending', - meta: { - type: 'boolean', - field: 'Cancelled', - index: 'kibana_sample_data_flights', - params: { - id: 'terms', - params: { - id: 'boolean', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - source: 'esaggs', - sourceParams: { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - id: '3', - enabled: true, - type: 'terms', - params: { - field: 'Cancelled', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - }, - }, - format: { - id: 'terms', - params: { - id: 'boolean', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - }, -] as Array>; - -const data = [ - { - 'col-0-2': 'Logstash Airways', - 'col-2-3': 0, - 'col-1-1': 726, - 'col-3-1': 624, - }, - { - 'col-0-2': 'Logstash Airways', - 'col-2-3': 1, - 'col-1-1': 726, - 'col-3-1': 102, - }, - { - 'col-0-2': 'JetBeats', - 'col-2-3': 0, - 'col-1-1': 703, - 'col-3-1': 602, - }, - { - 'col-0-2': 'JetBeats', - 'col-2-3': 1, - 'col-1-1': 703, - 'col-3-1': 101, - }, - { - 'col-0-2': 'ES-Air', - 'col-2-3': 0, - 'col-1-1': 667, - 'col-3-1': 601, - }, - { - 'col-0-2': 'ES-Air', - 'col-2-3': 1, - 'col-1-1': 667, - 'col-3-1': 66, - }, - { - 'col-0-2': 'Kibana Airlines', - 'col-2-3': 0, - 'col-1-1': 658, - 'col-3-1': 588, - }, - { - 'col-0-2': 'Kibana Airlines', - 'col-2-3': 1, - 'col-1-1': 658, - 'col-3-1': 70, - }, -]; +const bucketColumns = createMockBucketColumns(); +const visData = createMockVisData(); jest.mock('@elastic/charts', () => { const original = jest.requireActual('@elastic/charts'); @@ -180,9 +43,9 @@ describe('getColorPicker', function () { const Component: ComponentType = getColorPicker( 'left', jest.fn(), - layersColumns, + bucketColumns, 'default', - data + visData.rows ); let wrapper: ReactWrapper; @@ -224,9 +87,9 @@ describe('getColorPicker', function () { const LegacyPaletteComponent: ComponentType = getColorPicker( 'left', jest.fn(), - layersColumns, + bucketColumns, 'kibana_palette', - data + visData.rows ); const newProps = { ...wrapperProps, seriesIdentifier: { key: '1', specId: 'pie' } }; wrapper = mount(); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 9ac3e4091faacc..81e42a71e87e98 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -63,7 +63,7 @@ export const getColorPicker = ( seriesKey: string | number, event: BaseSyntheticEvent ) => void, - layerColumns: Array>, + bucketColumns: Array>, palette: string, data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { @@ -78,7 +78,7 @@ export const getColorPicker = ( // For the EuiPalette we want the user to be able to change only the colors of the inner layer if (palette !== 'kibana_palette') { - const enablePicker = isOnInnerLayer(layerColumns[0], data, seriesName); + const enablePicker = isOnInnerLayer(bucketColumns[0], data, seriesName); if (!enablePicker) return null; } const hexColor = new Color(color).hex(); @@ -96,8 +96,8 @@ export const getColorPicker = ( color={hexColor} onChange={handlChange} label={seriesName} - maxDepth={layerColumns.length} - layerIndex={getLayerIndex(seriesName, data, layerColumns)} + maxDepth={bucketColumns.length} + layerIndex={getLayerIndex(seriesName, data, bucketColumns)} /> ); diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts new file mode 100644 index 00000000000000..4bd375136b8165 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -0,0 +1,189 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { getColumns } from './get_columns'; +import { PieVisParams } from '../types'; +import { createMockPieParams, createMockVisData } from '../mocks'; + +const visParams = createMockPieParams(); +const visData = createMockVisData(); + +describe('getColumns', () => { + it('should return the correct bucket columns if visParams returns dimensions', () => { + const { bucketColumns } = getColumns(visParams, visData); + expect(bucketColumns.length).toEqual(visParams.dimensions.buckets?.length); + expect(bucketColumns).toEqual([ + { + format: { + id: 'terms', + params: { + id: 'string', + missingBucketLabel: 'Missing', + otherBucketLabel: 'Other', + }, + }, + id: 'col-0-2', + meta: { + field: 'Carrier', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'string', + missingBucketLabel: 'Missing', + otherBucketLabel: 'Other', + }, + }, + source: 'esaggs', + sourceParams: { + enabled: true, + id: '2', + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + params: { + field: 'Carrier', + missingBucket: false, + missingBucketLabel: 'Missing', + order: 'desc', + orderBy: '1', + otherBucket: false, + otherBucketLabel: 'Other', + size: 5, + }, + schema: 'segment', + type: 'terms', + }, + type: 'string', + }, + name: 'Carrier: Descending', + }, + { + format: { + id: 'terms', + params: { + id: 'boolean', + missingBucketLabel: 'Missing', + otherBucketLabel: 'Other', + }, + }, + id: 'col-2-3', + meta: { + field: 'Cancelled', + index: 'kibana_sample_data_flights', + params: { + id: 'terms', + params: { + id: 'boolean', + missingBucketLabel: 'Missing', + otherBucketLabel: 'Other', + }, + }, + source: 'esaggs', + sourceParams: { + enabled: true, + id: '3', + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + params: { + field: 'Cancelled', + missingBucket: false, + missingBucketLabel: 'Missing', + order: 'desc', + orderBy: '1', + otherBucket: false, + otherBucketLabel: 'Other', + size: 5, + }, + schema: 'segment', + type: 'terms', + }, + type: 'boolean', + }, + name: 'Cancelled: Descending', + }, + ]); + }); + + it('should return the correct metric column if visParams returns dimensions', () => { + const { metricColumn } = getColumns(visParams, visData); + expect(metricColumn).toEqual({ + id: 'col-3-1', + meta: { + index: 'kibana_sample_data_flights', + params: { id: 'number' }, + source: 'esaggs', + sourceParams: { + enabled: true, + id: '1', + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + params: {}, + schema: 'metric', + type: 'count', + }, + type: 'number', + }, + name: 'Count', + }); + }); + + it('should return the first data column if no buckets specified', () => { + const visParamsNoDimensions = ({ + addLegend: true, + addTooltip: true, + isDonut: true, + labels: { + position: 'default', + show: true, + truncate: 100, + values: true, + valuesFormat: 'percent', + }, + legendPosition: 'right', + nestedLegend: false, + palette: { + name: 'default', + type: 'palette', + }, + type: 'pie', + } as unknown) as PieVisParams; + const { metricColumn } = getColumns(visParamsNoDimensions, visData); + expect(metricColumn).toEqual(visData.columns[0]); + }); + + it('should return anwith the name of the metric if no buckets specified', () => { + const visParamsNoDimensions = ({ + addLegend: true, + addTooltip: true, + isDonut: true, + labels: { + position: 'default', + show: true, + truncate: 100, + values: true, + valuesFormat: 'percent', + }, + legendPosition: 'right', + nestedLegend: false, + palette: { + name: 'default', + type: 'palette', + }, + type: 'pie', + } as unknown) as PieVisParams; + const { bucketColumns, metricColumn } = getColumns(visParamsNoDimensions, visData); + expect(bucketColumns).toEqual([{ name: metricColumn.name }]); + }); +}); diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts new file mode 100644 index 00000000000000..ab38c810fa6907 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { DatatableColumn, Datatable } from '../../../expressions/public'; +import { BucketColumns, PieVisParams } from '../types'; + +export const getColumns = (visParams: PieVisParams, visData: Datatable) => { + const bucketColumns: Array> = []; + let metricColumn: DatatableColumn; + if (visParams?.dimensions?.buckets) { + visParams.dimensions.buckets.forEach((b) => { + bucketColumns.push({ ...visData.columns[b.accessor], format: b.format }); + }); + const lastBucketId = bucketColumns[bucketColumns.length - 1].id; + const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); + metricColumn = visData.columns[matchingIndex + 1]; + } else { + metricColumn = visData.columns[0]; + bucketColumns.push({ + name: metricColumn.name, + }); + } + return { + bucketColumns, + metricColumn, + }; +}; diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts new file mode 100644 index 00000000000000..ea3edc7b5d1485 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { PartitionConfig, PartitionLayout, RecursivePartial, Theme } from '@elastic/charts'; +import { LabelPositions, PieVisParams } from '../types'; + +export const getConfig = ( + visParams: PieVisParams, + chartTheme: RecursivePartial +): RecursivePartial => { + const config: RecursivePartial = { + partitionLayout: PartitionLayout.sunburst, + fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, + outerSizeRatio: 1, + specialFirstInnermostSector: true, + clockwiseSectors: false, + minFontSize: 10, + maxFontSize: 16, + linkLabel: { + maxCount: 5, + fontSize: 11, + textColor: chartTheme.axes?.axisTitle?.fill, + maxTextLength: visParams.labels.truncate ?? undefined, + }, + sectorLineStroke: chartTheme.lineSeriesStyle?.point?.fill, + sectorLineWidth: 1.5, + circlePadding: 4, + emptySizeRatio: visParams.isDonut ? 0.3 : 0, + }; + if (!visParams.labels.show) { + // Force all labels to be linked, then prevent links from showing + config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; + } + if (visParams.labels.position === LabelPositions.INSIDE) { + config.linkLabel = { maxCount: 0 }; + } + return config; +}; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 8721888918a880..d23cea793dcc5d 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -21,3 +21,5 @@ export { getLayers } from './get_layers'; export { getColorPicker } from './get_color_picker'; export { getLegendActions, ClickTriggerEvent } from './get_legend_actions'; export { canFilter, getFilterClickData, getFilterEventData } from './filter_helpers'; +export { getConfig } from './get_config'; +export { getColumns } from './get_columns'; From 328ef0e011141f5d1003b28cd04a7a1a7558b41f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 7 Dec 2020 11:49:40 +0200 Subject: [PATCH 020/111] Add jest config file --- src/plugins/vis_type_pie/jest.config.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/plugins/vis_type_pie/jest.config.js diff --git a/src/plugins/vis_type_pie/jest.config.js b/src/plugins/vis_type_pie/jest.config.js new file mode 100644 index 00000000000000..f31a0d718d9e16 --- /dev/null +++ b/src/plugins/vis_type_pie/jest.config.js @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/src/plugins/vis_type_pie'], +}; From 20a7ecbf3274ae4166215a03a45fbf4a8739b8d7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 8 Dec 2020 17:29:10 +0200 Subject: [PATCH 021/111] Fix jest test --- .../public/editor/components/palette_picker.test.tsx | 8 -------- .../public/editor/components/palette_picker.tsx | 1 - 2 files changed, 9 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx index 0574a478776196..1b4d7e060296ae 100644 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx @@ -20,7 +20,6 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { ReactWrapper } from 'enzyme'; import { PalettePicker, PalettePickerProps } from './palette_picker'; -import { findTestSubject } from '@elastic/eui/lib/test'; import { chartPluginMock } from '../../../../charts/public/mocks'; import { EuiColorPalettePicker } from '@elastic/eui'; @@ -57,11 +56,4 @@ describe('PalettePicker', function () { const palettePicker = component.find(EuiColorPalettePicker); expect(palettePicker.props().valueOfSelected).toBe('kibana_palette'); }); - - it('should set the new palette', function () { - component = mountWithIntl(); - const input = findTestSubject(component, 'piePalettePicker'); - input.simulate('change', { target: { value: 'temperature' } }); - expect(props.setPalette).toHaveBeenCalled(); - }); }); diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx index 144288db6342e2..1e7088581c0f53 100644 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx @@ -24,7 +24,6 @@ import { EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; export interface PalettePickerProps { - 'data-test-subj'?: string; activePalette?: PaletteOutput; palettes: PaletteRegistry; paramName: ParamName; From 885b1e47d0f014f35dde40de20ce97ade3cdaf9e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 8 Dec 2020 17:31:14 +0200 Subject: [PATCH 022/111] fix api integration failure --- test/api_integration/apis/saved_objects/find.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api_integration/apis/saved_objects/find.js b/test/api_integration/apis/saved_objects/find.js index 8e8730b1e574a5..b280809b18d5c5 100644 --- a/test/api_integration/apis/saved_objects/find.js +++ b/test/api_integration/apis/saved_objects/find.js @@ -195,7 +195,7 @@ export default function ({ getService }) { }, id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', migrationVersion: { - visualization: '7.10.0', + visualization: '7.12.0', }, namespaces: ['foo-ns'], references: [ From 85ecefadb24779d740020b2237eb70cb70ad570a Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 15 Dec 2020 09:50:38 +0200 Subject: [PATCH 023/111] Fix to_ast_esaggs for new pie plugin --- .../vis_type_pie/public/to_ast_esaggs.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts index 1a0418251b960d..78bda37fc6975c 100644 --- a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts +++ b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts @@ -18,23 +18,27 @@ */ import { Vis } from '../../visualizations/public'; -import { buildExpressionFunction } from '../../expressions/public'; -import { EsaggsExpressionFunctionDefinition } from '../../data/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { + EsaggsExpressionFunctionDefinition, + IndexPatternLoadExpressionFunctionDefinition, +} from '../../data/public'; import { PieVisParams } from './types'; /** * Get esaggs expressions function - * TODO: replace this with vis.data.aggs!.toExpressionAst(); - * https://github.com/elastic/kibana/issues/61768 * @param vis */ export function getEsaggsFn(vis: Vis) { return buildExpressionFunction('esaggs', { - index: vis.data.indexPattern!.id!, + index: buildExpression([ + buildExpressionFunction('indexPatternLoad', { + id: vis.data.indexPattern!.id!, + }), + ]), metricsAtAllLevels: vis.isHierarchical(), partialRows: false, - aggConfigs: JSON.stringify(vis.data.aggs!.aggs), - includeFormatHints: false, + aggs: vis.data.aggs!.aggs.map((agg) => buildExpression(agg.toExpressionAst())), }); } From f96296cf298b92535a1b74f4bb5e9a40ac1679d3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 15 Dec 2020 11:11:58 +0200 Subject: [PATCH 024/111] Close legendColorPicker popover when user clicks outside --- .../public/utils/get_color_picker.test.tsx | 4 +-- .../public/utils/get_color_picker.tsx | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index 3f2e57aa113f66..0b29c2b77ffd55 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; import { LegendColorPickerProps } from '@elastic/charts'; -import { EuiWrappingPopover } from '@elastic/eui'; +import { EuiPopover } from '@elastic/eui'; import { mount } from 'enzyme'; import { ComponentType, ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; @@ -69,7 +69,7 @@ describe('getColorPicker', function () { it('renders the picker on the correct position', () => { wrapper = mount(); - expect(wrapper.find(EuiWrappingPopover).prop('anchorPosition')).toEqual('rightCenter'); + expect(wrapper.find(EuiPopover).prop('anchorPosition')).toEqual('rightCenter'); }); it('converts the color to the right hex and passes it to the color picker', () => { diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 81e42a71e87e98..c06a2d2ebb6b80 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -17,10 +17,10 @@ * under the License. */ -import React, { BaseSyntheticEvent } from 'react'; +import React, { BaseSyntheticEvent, useRef, useEffect, useCallback } from 'react'; import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; -import { PopoverAnchorPosition, EuiWrappingPopover } from '@elastic/eui'; +import { PopoverAnchorPosition, EuiPopover } from '@elastic/eui'; import { DatatableRow } from '../../../expressions/public'; import { BucketColumns } from '../types'; import { ColorPicker } from '../temp'; @@ -67,15 +67,35 @@ export const getColorPicker = ( palette: string, data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { + const ref = useRef(null); const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { - onClose(); + if (!seriesName) { + return; + } if (newColor) { onChange(newColor); } setColor(newColor, seriesName, event); + onClose(); }; + const handleOutsideClick = useCallback( + (e: MouseEvent) => { + if (!(ref.current! as any).contains(e.target)) { + onClose?.(); + } + }, + [onClose] + ); + + useEffect(() => { + document.addEventListener('click', handleOutsideClick); + return () => { + document.removeEventListener('click', handleOutsideClick); + }; + }, [handleOutsideClick]); + // For the EuiPalette we want the user to be able to change only the colors of the inner layer if (palette !== 'kibana_palette') { const enablePicker = isOnInnerLayer(bucketColumns[0], data, seriesName); @@ -83,7 +103,8 @@ export const getColorPicker = ( } const hexColor = new Color(color).hex(); return ( - - + ); }; From b256e8df6218085fbe963969e6bc13b089ee1b27 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 15 Dec 2020 11:55:29 +0200 Subject: [PATCH 025/111] Fix warning --- src/plugins/vis_type_pie/public/utils/get_color_picker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index c06a2d2ebb6b80..cd7b0a71739912 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -82,7 +82,7 @@ export const getColorPicker = ( const handleOutsideClick = useCallback( (e: MouseEvent) => { - if (!(ref.current! as any).contains(e.target)) { + if (ref.current && !(ref.current! as any).contains(e.target)) { onClose?.(); } }, From f8c48f902d801e33602504e82a50746951119431 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 16 Dec 2020 10:40:10 +0200 Subject: [PATCH 026/111] Remove getter/setters and refactor --- .../public/editor/components/index.tsx | 5 +- .../public/editor/components/pie.tsx | 30 ++++++++---- .../public/pie_component.test.tsx | 18 ++----- .../vis_type_pie/public/pie_component.tsx | 22 ++++++--- .../vis_type_pie/public/pie_renderer.tsx | 21 ++++++--- src/plugins/vis_type_pie/public/plugin.ts | 40 +++++++++------- src/plugins/vis_type_pie/public/services.ts | 47 ------------------- .../public/utils/filter_helpers.ts | 9 ++-- .../vis_type_pie/public/utils/get_layers.ts | 12 ++--- .../public/utils/get_legend_actions.tsx | 16 ++++--- .../vis_type_pie/public/vis_type/index.ts | 6 +-- .../vis_type_pie/public/vis_type/pie.ts | 8 ++-- 12 files changed, 111 insertions(+), 123 deletions(-) delete mode 100644 src/plugins/vis_type_pie/public/services.ts diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index 893fdaf2d01a7f..745f335f0d171d 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -19,8 +19,11 @@ import React, { lazy } from 'react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; +import { PaletteRegistry } from 'src/plugins/charts/public'; import { PieVisParams } from '../../types'; const PieOptionsLazy = lazy(() => import('./pie')); -export const PieOptions = (props: VisOptionsProps) => ; +export const getPieOptions = (palettes: PaletteRegistry | undefined) => ( + props: VisOptionsProps +) => ; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 9d4d671560bfb2..6ad1f6650a9a40 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -25,12 +25,20 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; import { PalettePicker } from './palette_picker'; -import { BasicOptions, SwitchOption, SelectOption } from '../../../../charts/public'; +import { + BasicOptions, + SwitchOption, + SelectOption, + PaletteRegistry, +} from '../../../../charts/public'; import { PieVisParams } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; -import { getColorsService } from '../../services'; -function PieOptions(props: VisOptionsProps) { +interface PieOptionsProps extends VisOptionsProps { + palettes: PaletteRegistry | undefined; +} + +const PieOptions = (props: PieOptionsProps) => { const { stateParams, setValue } = props; const setLabels = ( paramName: T, @@ -66,12 +74,14 @@ function PieOptions(props: VisOptionsProps) { value={stateParams.nestedLegend} setValue={setValue} /> - + {props.palettes && ( + + )} @@ -126,7 +136,7 @@ function PieOptions(props: VisOptionsProps) { ); -} +}; // default export required for React.Lazy // eslint-disable-next-line import/no-default-export diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index a3eab40f7d88cb..56d94e6a95f2c1 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -19,22 +19,12 @@ import React from 'react'; import { Settings, TooltipType, SeriesIdentifier } from '@elastic/charts'; import { chartPluginMock } from '../../charts/public/mocks'; +import { dataPluginMock } from '../../data/public/mocks'; import { shallow, mount } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import PieComponent, { PieComponentProps } from './pie_component'; import { createMockPieParams, createMockVisData } from './mocks'; -jest.mock('./services', () => ({ - getColorsService: jest.fn().mockReturnValue({ - get: jest.fn(), - getAll: jest.fn(), - }), - getFormatService: jest.fn().mockReturnValue({ - deserialize: jest.fn(), - getAll: jest.fn(), - }), -})); - jest.mock('@elastic/charts', () => { const original = jest.requireActual('@elastic/charts'); @@ -45,6 +35,7 @@ jest.mock('@elastic/charts', () => { }); const chartsThemeService = chartPluginMock.createSetupContract().theme; +const palettes = chartPluginMock.createPaletteRegistry(); const visParams = createMockPieParams(); const visData = createMockVisData(); @@ -64,11 +55,13 @@ describe('PieComponent', function () { beforeAll(() => { wrapperProps = { chartsThemeService, + palettes, visParams, visData, uiState, fireEvent: jest.fn(), renderComplete: jest.fn(), + services: dataPluginMock.createStartContract(), }; }); @@ -84,8 +77,7 @@ describe('PieComponent', function () { it('hides the legend if the legend toggle is clicked', () => { const component = mount(); - const toggle = findTestSubject(component, 'vislibToggleLegend'); - toggle.simulate('click'); + findTestSubject(component, 'vislibToggleLegend').simulate('click'); expect(component.find(Settings).prop('showLegend')).toEqual(false); }); diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index cfe75dd4eca48f..83973cd4b2441c 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -46,10 +46,11 @@ import { // LegendToggle, // ClickTriggerEvent, ChartsPluginSetup, + PaletteRegistry, } from '../../charts/public'; +import { DataPublicPluginStart } from '../../data/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { PieVisParams, BucketColumns, ValueFormats } from './types'; -import { getFormatService } from './services'; import { getColorPicker, getLayers, @@ -72,6 +73,8 @@ export interface PieComponentProps { fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; chartsThemeService: ChartsPluginSetup['theme']; + palettes: PaletteRegistry; + services: DataPublicPluginStart; } const PieComponent = (props: PieComponentProps) => { @@ -160,7 +163,7 @@ const PieComponent = (props: PieComponentProps) => { [props.uiState] ); - const { visData, visParams } = props; + const { visData, visParams, palettes, services } = props; function getSliceValue(d: Datum, metricColumn: DatatableColumn) { if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { @@ -170,8 +173,10 @@ const PieComponent = (props: PieComponentProps) => { } // formatters - const metricFieldFormatter = getFormatService().deserialize(visParams.dimensions.metric.format); - const percentFormatter = getFormatService().deserialize({ + const metricFieldFormatter = services.fieldFormats.deserialize( + visParams.dimensions.metric.format + ); + const percentFormatter = services.fieldFormats.deserialize({ id: 'percent', params: { pattern: '0.[00]%', @@ -190,9 +195,10 @@ const PieComponent = (props: PieComponentProps) => { visParams, props.uiState?.get('vis.colors', {}), visData.rows.length, - visParams.palette.name + palettes, + services.fieldFormats ), - [bucketColumns, props.uiState, visData.rows.length, visParams] + [bucketColumns, palettes, props.uiState, services.fieldFormats, visData.rows.length, visParams] ); const config = useMemo(() => getConfig(visParams, chartTheme), [chartTheme, visParams]); const tooltip: TooltipProps = { @@ -230,7 +236,9 @@ const PieComponent = (props: PieComponentProps) => { canFilter, getLegendActionEventData(visData), handleLegendAction, - visParams + visParams, + services.actions, + services.fieldFormats )} theme={chartTheme} baseTheme={chartBaseTheme} diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 8ce899dfc3064e..e38fd63792c1aa 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -22,10 +22,10 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { ExpressionRenderDefinition } from '../../expressions/public'; import { VisualizationContainer } from '../../visualizations/public'; +import { VisTypePieDependencies } from './plugin'; // import { SplitChartWarning } from './components'; import { RenderValue, vislibPieName } from './pie_fn'; -import { getThemeService } from './services'; const PieComponent = lazy(() => import('./pie_component')); @@ -36,30 +36,39 @@ function shouldShowNoResultsMessage(visData: any): boolean { return Boolean(isZeroHits); } -export const pieVisRenderer: ExpressionRenderDefinition = { +export const getPieVisRenderer: ( + deps: VisTypePieDependencies +) => ExpressionRenderDefinition = ({ theme, palettes, getStartDeps }) => ({ name: vislibPieName, displayName: 'Pie visualization', reuseDomNode: true, - render: (domNode, { visConfig, visData }, handlers) => { + render: async (domNode, { visConfig, visData }, handlers) => { const showNoResult = shouldShowNoResultsMessage(visData); const isSplitChart = Boolean(visConfig.dimensions.splitRow); - handlers.onDestroy(() => unmountComponentAtNode(domNode)); + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + const services = await getStartDeps(); + render( <> {/* {isSplitChart && } */} , domNode ); }, -}; +}); diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index a9a4c7e7036ebb..93296217d17e45 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -19,45 +19,49 @@ import { CoreSetup, CoreStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; -import { ChartsPluginSetup } from '../../charts/public'; +import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; import { createPieVisFn } from './pie_fn'; -import { pieVisRenderer } from './pie_renderer'; +import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; -import { setThemeService, setColorsService, setFormatService, setDataActions } from './services'; +/** @internal */ export interface VisTypePieSetupDependencies { visualizations: VisualizationsSetup; expressions: ReturnType; charts: ChartsPluginSetup; } +/** @internal */ export interface VisTypePiePluginStartDependencies { data: DataPublicPluginStart; } +/** @internal */ +export interface VisTypePieDependencies { + theme: ChartsPluginSetup['theme']; + palettes: PaletteRegistry; + getStartDeps: () => Promise; +} + export class VisTypePiePlugin { setup( core: CoreSetup, { expressions, visualizations, charts }: VisTypePieSetupDependencies ) { - // temporary, add it as arg to pieVisRenderer - setThemeService(charts.theme); - // setColorsService(charts.palettes); - charts.palettes.getPalettes().then((palettes) => { - setColorsService(palettes); - }); + const getStartDeps = async () => { + const [, deps] = await core.getStartServices(); + return deps.data; + }; [createPieVisFn].forEach(expressions.registerFunction); - expressions.registerRenderer(pieVisRenderer); - visualizations.createBaseVisualization(pieVisType(true)); - // core.getStartServices().then(([coreStart]) => { - // visualizations.registerAlias(getLensAliasConfig(coreStart.docLinks)); - // }); + charts.palettes.getPalettes().then((palettes) => { + expressions.registerRenderer( + getPieVisRenderer({ theme: charts.theme, palettes, getStartDeps }) + ); + visualizations.createBaseVisualization(pieVisType(true, palettes)); + }); } - start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) { - setFormatService(data.fieldFormats); - setDataActions(data.actions); - } + start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) {} } diff --git a/src/plugins/vis_type_pie/public/services.ts b/src/plugins/vis_type_pie/public/services.ts deleted file mode 100644 index e2b2ef5ba65ba6..00000000000000 --- a/src/plugins/vis_type_pie/public/services.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { CoreSetup } from '../../../core/public'; -import { createGetterSetter } from '../../kibana_utils/public'; -import { DataPublicPluginStart } from '../../data/public'; -import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; - -export const [getUISettings, setUISettings] = createGetterSetter( - 'pie core.uiSettings' -); - -export const [getDataActions, setDataActions] = createGetterSetter< - DataPublicPluginStart['actions'] ->('pie data.actions'); - -export const [getFormatService, setFormatService] = createGetterSetter< - DataPublicPluginStart['fieldFormats'] ->('pie data.fieldFormats'); - -export const [getTimefilter, setTimefilter] = createGetterSetter< - DataPublicPluginStart['query']['timefilter']['timefilter'] ->('pie data.query.timefilter.timefilter'); - -export const [getThemeService, setThemeService] = createGetterSetter( - 'pie charts.theme' -); - -export const [getColorsService, setColorsService] = createGetterSetter( - 'pie charts.color' -); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 4348857b12eaa0..12ca2632ac0a6d 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -18,16 +18,19 @@ */ import { LayerValue, SeriesIdentifier } from '@elastic/charts'; import { Datatable } from '../../../expressions/public'; +import { DataPublicPluginStart } from '../../../data/public'; import { ValueClickContext } from '../../../embeddable/public'; import { ClickTriggerEvent } from './get_legend_actions'; -import { getDataActions } from '../services'; import { BucketColumns } from '../types'; -export const canFilter = async (event: ClickTriggerEvent | null): Promise => { +export const canFilter = async ( + event: ClickTriggerEvent | null, + actions: DataPublicPluginStart['actions'] +): Promise => { if (!event) { return false; } - const filters = await getDataActions().createFiltersFromValueClickAction(event.data); + const filters = await actions.createFiltersFromValueClickAction(event.data); return Boolean(filters.length); }; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 1f30571a79972d..6035e1e11b546b 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -18,10 +18,10 @@ */ import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; -import { SeriesLayer } from '../../../charts/public'; +import { SeriesLayer, PaletteRegistry } from '../../../charts/public'; +import { DataPublicPluginStart } from '../../../data/public'; import { BucketColumns, PieVisParams } from '../types'; import { lightenColor } from '../temp'; -import { getFormatService, getColorsService } from '../services'; const EMPTY_SLICE = Symbol('empty_slice'); @@ -30,7 +30,8 @@ export const getLayers = ( visParams: PieVisParams, overwriteColors: { [key: string]: string }, totalSeries: number, - palette: string + palettes: PaletteRegistry, + formatter: DataPublicPluginStart['fieldFormats'] ): PartitionLayer[] => { const fillLabel: Partial = { textInvertible: true, @@ -38,7 +39,6 @@ export const getLayers = ( fontWeight: 700, }, }; - const defaultPalette = getColorsService().get(palette); if (!visParams.labels.values) { fillLabel.valueFormatter = () => ''; @@ -56,7 +56,7 @@ export const getLayers = ( }); } if (col?.meta?.params) { - return getFormatService().deserialize(col.format).convert(d) ?? ''; + return formatter.deserialize(col.format).convert(d) ?? ''; } return String(d); }, @@ -88,7 +88,7 @@ export const getLayers = ( return lightenColor(overwriteColor, seriesLayers.length, columns.length); } - const outputColor = defaultPalette.getColor(seriesLayers, { + const outputColor = palettes.get(visParams.palette.name).getColor(seriesLayers, { behindText: visParams.labels.show, maxDepth: columns.length, totalSeries, diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 7beb4fcaa5badc..2596c1090c0241 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -23,9 +23,8 @@ import { i18n } from '@kbn/i18n'; import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; import { LegendAction, SeriesIdentifier } from '@elastic/charts'; import { ValueClickContext } from '../../../embeddable/public'; +import { DataPublicPluginStart } from '../../../data/public'; import { PieVisParams } from '../types'; -import { getFormatService } from '../services'; - // import { ClickTriggerEvent } from '../../../charts/public'; // this is temporary @@ -35,17 +34,22 @@ export interface ClickTriggerEvent { } export const getLegendActions = ( - canFilter: (data: ClickTriggerEvent | null) => Promise, + canFilter: ( + data: ClickTriggerEvent | null, + actions: DataPublicPluginStart['actions'] + ) => Promise, getFilterEventData: (series: SeriesIdentifier) => ClickTriggerEvent | null, onFilter: (data: ClickTriggerEvent, negate?: any) => void, - visParams: PieVisParams + visParams: PieVisParams, + actions: DataPublicPluginStart['actions'], + formatter: DataPublicPluginStart['fieldFormats'] ): LegendAction => { return ({ series }) => { const [popoverOpen, setPopoverOpen] = useState(false); const [isfilterable, setIsfilterable] = useState(true); const filterData = getFilterEventData(series); - (async () => setIsfilterable(await canFilter(filterData)))(); + (async () => setIsfilterable(await canFilter(filterData, actions)))(); if (!isfilterable || !filterData) { return null; @@ -56,7 +60,7 @@ export const getLegendActions = ( const column = visParams.dimensions.buckets.find( (bucket) => bucket.accessor === filterData.data.data[0].column ); - formattedTitle = getFormatService().deserialize(column?.format).convert(series.key) ?? ''; + formattedTitle = formatter.deserialize(column?.format).convert(series.key) ?? ''; } const title = formattedTitle || series.key; diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index 8e7334bd9fbc0a..ab191542d0d498 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ - +import { PaletteRegistry } from '../../../charts/public'; import { getPieVisTypeDefinition } from './pie'; -export const pieVisType = (showElasticChartsOptions?: boolean) => { - return getPieVisTypeDefinition(showElasticChartsOptions); +export const pieVisType = (showElasticChartsOptions?: boolean, palettes?: PaletteRegistry) => { + return getPieVisTypeDefinition(showElasticChartsOptions, palettes); }; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index a724848ff2fbb0..08151796501fa7 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -24,15 +24,17 @@ import { Position } from '@elastic/charts'; import { Schemas } from '../../../vis_default_editor/public'; import { AggGroupNames } from '../../../data/public'; +import { PaletteRegistry } from '../../../charts/public'; import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualizations/public'; import { PieVisParams, LabelPositions, ValueFormats } from '../types'; import { toExpressionAst } from '../to_ast'; import { getLegendPositions } from '../editor'; -import { PieOptions } from '../editor/components'; +import { getPieOptions } from '../editor/components'; export const getPieVisTypeDefinition = ( - showElasticChartsOptions = false + showElasticChartsOptions = false, + palettes: PaletteRegistry | undefined ): BaseVisTypeOptions => ({ name: 'pie', title: i18n.translate('visTypePie.pie.pieTitle', { defaultMessage: 'Pie' }), @@ -67,7 +69,7 @@ export const getPieVisTypeDefinition = ( collections: { legendPositions: getLegendPositions(), }, - optionsTemplate: PieOptions, + optionsTemplate: getPieOptions(palettes), schemas: new Schemas([ { group: AggGroupNames.Metrics, From a680be246cb9631969b82ccea9b31341ebe76e5f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 16 Dec 2020 13:03:22 +0200 Subject: [PATCH 027/111] Remove kibanaUtils from pie plugin as it is not needed --- src/plugins/vis_type_pie/kibana.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/kibana.json b/src/plugins/vis_type_pie/kibana.json index 6b661b817258ea..bbefe784fd6850 100644 --- a/src/plugins/vis_type_pie/kibana.json +++ b/src/plugins/vis_type_pie/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor"] + "requiredBundles": ["visDefaultEditor"] } \ No newline at end of file From 365cf08cf066455a8c73c9053a70ac5dc0117a00 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Dec 2020 14:22:16 +0200 Subject: [PATCH 028/111] Add new values to the migration script --- .../server/saved_objects/visualization_migrations.test.ts | 8 ++++++++ .../server/saved_objects/visualization_migrations.ts | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index ae1b0bee9ccc50..34f6672da81c09 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1717,5 +1717,13 @@ describe('migration visualization', () => { expect(palette.name).toEqual('kibana_palette'); }); + + it('should decorate existing docs with the new labels settings', () => { + const migratedTestDoc = migrate(generateDoc()); + const { labels } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(labels.valuesFormat).toEqual('percent'); + expect(labels.position).toEqual('default'); + }); }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 09fb218522598e..e148b137b4f5b6 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -781,6 +781,11 @@ const migrateVislibPie: SavedObjectMigrationFn = (doc) => { type: 'palette', name: 'kibana_palette', }, + labels: { + ...visState.params.labels, + valuesFormat: 'percent', + position: 'default', + }, }, }), }, From a5d0eae604ea8849b921078f5e6aa0c3c58afb3e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Dec 2020 14:42:55 +0200 Subject: [PATCH 029/111] Fix bug on not changing color for expty string --- src/plugins/vis_type_pie/public/utils/get_color_picker.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index cd7b0a71739912..dba5240b2048d6 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -70,9 +70,6 @@ export const getColorPicker = ( const ref = useRef(null); const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { - if (!seriesName) { - return; - } if (newColor) { onChange(newColor); } From d89527c0dcbf87d46c2ff40d994d5fe21f994e4f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Dec 2020 14:59:31 +0200 Subject: [PATCH 030/111] remove from migration script as they don't need it --- src/plugins/vis_type_pie/public/editor/components/pie.tsx | 6 +++--- .../server/saved_objects/visualization_migrations.test.ts | 8 -------- .../server/saved_objects/visualization_migrations.ts | 5 ----- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 6ad1f6650a9a40..63d96dcdf6abf1 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -31,7 +31,7 @@ import { SelectOption, PaletteRegistry, } from '../../../../charts/public'; -import { PieVisParams } from '../../types'; +import { PieVisParams, LabelPositions, ValueFormats } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; interface PieOptionsProps extends VisOptionsProps { @@ -111,7 +111,7 @@ const PieOptions = (props: PieOptionsProps) => { disabled={!stateParams.labels.show} options={getLabelPositions()} paramName="position" - value={stateParams.labels.position} + value={stateParams.labels.position || LabelPositions.DEFAULT} setValue={setLabels} /> { disabled={!stateParams.labels.values} options={getValuesFormats()} paramName="valuesFormat" - value={stateParams.labels.valuesFormat} + value={stateParams.labels.valuesFormat || ValueFormats.PERCENT} setValue={setLabels} /> diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index 34f6672da81c09..ae1b0bee9ccc50 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1717,13 +1717,5 @@ describe('migration visualization', () => { expect(palette.name).toEqual('kibana_palette'); }); - - it('should decorate existing docs with the new labels settings', () => { - const migratedTestDoc = migrate(generateDoc()); - const { labels } = JSON.parse(migratedTestDoc.attributes.visState).params; - - expect(labels.valuesFormat).toEqual('percent'); - expect(labels.position).toEqual('default'); - }); }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index e148b137b4f5b6..09fb218522598e 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -781,11 +781,6 @@ const migrateVislibPie: SavedObjectMigrationFn = (doc) => { type: 'palette', name: 'kibana_palette', }, - labels: { - ...visState.params.labels, - valuesFormat: 'percent', - position: 'default', - }, }, }), }, From 4010a92d3232a14bb2869ea4e6eeca684e18ba04 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 11:04:04 +0200 Subject: [PATCH 031/111] Fix editor settings for old and new implementation --- src/plugins/vis_type_pie/common/index.ts | 20 ++++ .../public/editor/components/index.tsx | 13 ++- .../public/editor/components/pie.tsx | 75 ++++++++----- src/plugins/vis_type_pie/public/plugin.ts | 26 +++-- .../vis_type_pie/public/types/params.ts | 1 + .../vis_type_pie/public/vis_type/pie.ts | 3 +- .../public/editor/components/index.tsx | 4 - .../public/editor/components/pie.tsx | 105 ------------------ 8 files changed, 94 insertions(+), 153 deletions(-) create mode 100644 src/plugins/vis_type_pie/common/index.ts delete mode 100644 src/plugins/vis_type_vislib/public/editor/components/pie.tsx diff --git a/src/plugins/vis_type_pie/common/index.ts b/src/plugins/vis_type_pie/common/index.ts new file mode 100644 index 00000000000000..9b7e834d6ce0f4 --- /dev/null +++ b/src/plugins/vis_type_pie/common/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index 745f335f0d171d..f69a42ebec93c7 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -24,6 +24,13 @@ import { PieVisParams } from '../../types'; const PieOptionsLazy = lazy(() => import('./pie')); -export const getPieOptions = (palettes: PaletteRegistry | undefined) => ( - props: VisOptionsProps -) => ; +export const getPieOptions = ( + palettes: PaletteRegistry | undefined, + showElasticChartsOptions: boolean +) => (props: VisOptionsProps) => ( + +); diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 63d96dcdf6abf1..a9edfc001bf175 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -36,6 +36,7 @@ import { getLabelPositions, getValuesFormats } from '../collections'; interface PieOptionsProps extends VisOptionsProps { palettes: PaletteRegistry | undefined; + showElasticChartsOptions: boolean; } const PieOptions = (props: PieOptionsProps) => { @@ -66,15 +67,17 @@ const PieOptions = (props: PieOptionsProps) => { setValue={setValue} /> - - {props.palettes && ( + {props.showElasticChartsOptions && ( + + )} + {props.showElasticChartsOptions && props.palettes && ( { value={stateParams.labels.show} setValue={setLabels} /> - + {props.showElasticChartsOptions && ( + + )} + {!props.showElasticChartsOptions && ( + + )} { value={stateParams.labels.values} setValue={setLabels} /> - + {props.showElasticChartsOptions && ( + + )} diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 93296217d17e45..d3bb8c1d3310e0 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -21,6 +21,7 @@ import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; +import { LEGACY_CHARTS_LIBRARY } from '../common'; import { createPieVisFn } from './pie_fn'; import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; @@ -49,18 +50,21 @@ export class VisTypePiePlugin { core: CoreSetup, { expressions, visualizations, charts }: VisTypePieSetupDependencies ) { - const getStartDeps = async () => { - const [, deps] = await core.getStartServices(); - return deps.data; - }; + if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) { + const getStartDeps = async () => { + const [, deps] = await core.getStartServices(); + return deps.data; + }; - [createPieVisFn].forEach(expressions.registerFunction); - charts.palettes.getPalettes().then((palettes) => { - expressions.registerRenderer( - getPieVisRenderer({ theme: charts.theme, palettes, getStartDeps }) - ); - visualizations.createBaseVisualization(pieVisType(true, palettes)); - }); + [createPieVisFn].forEach(expressions.registerFunction); + charts.palettes.getPalettes().then((palettes) => { + expressions.registerRenderer( + getPieVisRenderer({ theme: charts.theme, palettes, getStartDeps }) + ); + visualizations.createBaseVisualization(pieVisType(true, palettes)); + }); + } + return {}; } start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) {} diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/params.ts index bdee5f7365cf1e..4308fe21d61bba 100644 --- a/src/plugins/vis_type_pie/public/types/params.ts +++ b/src/plugins/vis_type_pie/public/types/params.ts @@ -46,6 +46,7 @@ export interface PieVisParams { palette: PaletteOutput; labels: { show: boolean; + last_level: boolean; position: LabelPositions; values: boolean; truncate: number | null; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 08151796501fa7..ada5d350a9f720 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -58,6 +58,7 @@ export const getPieVisTypeDefinition = ( }, labels: { show: true, + last_level: true, values: true, valuesFormat: ValueFormats.PERCENT, truncate: 100, @@ -69,7 +70,7 @@ export const getPieVisTypeDefinition = ( collections: { legendPositions: getLegendPositions(), }, - optionsTemplate: getPieOptions(palettes), + optionsTemplate: getPieOptions(palettes, showElasticChartsOptions), schemas: new Schemas([ { group: AggGroupNames.Metrics, diff --git a/src/plugins/vis_type_vislib/public/editor/components/index.tsx b/src/plugins/vis_type_vislib/public/editor/components/index.tsx index ed8c8239a07b6f..9dd8e956f44e51 100644 --- a/src/plugins/vis_type_vislib/public/editor/components/index.tsx +++ b/src/plugins/vis_type_vislib/public/editor/components/index.tsx @@ -22,19 +22,15 @@ import React, { lazy } from 'react'; import { VisOptionsProps } from '../../../../vis_default_editor/public'; import { GaugeVisParams } from '../../gauge'; -import { PieVisParams } from '../../pie'; import { HeatmapVisParams } from '../../heatmap'; const GaugeOptionsLazy = lazy(() => import('./gauge')); -const PieOptionsLazy = lazy(() => import('./pie')); const HeatmapOptionsLazy = lazy(() => import('./heatmap')); export const GaugeOptions = (props: VisOptionsProps) => ( ); -export const PieOptions = (props: VisOptionsProps) => ; - export const HeatmapOptions = (props: VisOptionsProps) => ( ); diff --git a/src/plugins/vis_type_vislib/public/editor/components/pie.tsx b/src/plugins/vis_type_vislib/public/editor/components/pie.tsx deleted file mode 100644 index 1c3aa501b4d008..00000000000000 --- a/src/plugins/vis_type_vislib/public/editor/components/pie.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import React from 'react'; - -import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { VisOptionsProps } from '../../../../vis_default_editor/public'; -import { BasicOptions, SwitchOption } from '../../../../charts/public'; -import { TruncateLabelsOption } from '../../../../vis_type_xy/public'; - -import { PieVisParams } from '../../pie'; - -function PieOptions(props: VisOptionsProps) { - const { stateParams, setValue } = props; - const setLabels = ( - paramName: T, - value: PieVisParams['labels'][T] - ) => setValue('labels', { ...stateParams.labels, [paramName]: value }); - - return ( - <> - - -

- -

-
- - - -
- - - - - -

- -

-
- - - - - -
- - ); -} - -// default export required for React.Lazy -// eslint-disable-next-line import/no-default-export -export { PieOptions as default }; From bad9e48e182d9564003e16f40bd0902f9a6d20fb Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 11:09:36 +0200 Subject: [PATCH 032/111] fix uistate type --- src/plugins/vis_type_pie/public/pie_component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 83973cd4b2441c..d50bacd8c3cb33 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -49,6 +49,7 @@ import { PaletteRegistry, } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; +import type { PersistedState } from '../../visualizations/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { PieVisParams, BucketColumns, ValueFormats } from './types'; import { @@ -69,7 +70,7 @@ import './chart.scss'; export interface PieComponentProps { visParams: PieVisParams; visData: Datatable; - uiState: IInterpreterRenderHandlers['uiState']; + uiState: PersistedState; fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; chartsThemeService: ChartsPluginSetup['theme']; From 259b132b5ad365270f5b6c51d436dfa3b3fef6d1 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 12:04:20 +0200 Subject: [PATCH 033/111] Disable split chart for the new plugin for now --- .../public/components/split_chart_warning.tsx | 60 +++++++++++++++++++ .../vis_type_pie/public/pie_renderer.tsx | 9 +-- src/plugins/vis_type_pie/public/plugin.ts | 12 ++-- .../public/vis_type/{pie.ts => pie.tsx} | 9 ++- .../public/vis_type/split_tooltip.tsx | 31 ++++++++++ 5 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/components/split_chart_warning.tsx rename src/plugins/vis_type_pie/public/vis_type/{pie.ts => pie.tsx} (93%) create mode 100644 src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx diff --git a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx new file mode 100644 index 00000000000000..76769e5ded4fca --- /dev/null +++ b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { EuiLink, EuiCallOut } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { DocLinksStart } from 'src/core/public'; + +interface SplitChartWarningProps { + docLinks: DocLinksStart; +} + +export function SplitChartWarning({ docLinks }: SplitChartWarningProps) { + const advancedSettingsLink = docLinks.links.management.visualizationSettings; + + return ( + + + + + + ), + }} + /> + + + ); +} diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index e38fd63792c1aa..69d7a9baded364 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -22,8 +22,9 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { ExpressionRenderDefinition } from '../../expressions/public'; import { VisualizationContainer } from '../../visualizations/public'; +import type { PersistedState } from '../../visualizations/public'; import { VisTypePieDependencies } from './plugin'; -// import { SplitChartWarning } from './components'; +import { SplitChartWarning } from './components/split_chart_warning'; import { RenderValue, vislibPieName } from './pie_fn'; @@ -54,7 +55,7 @@ export const getPieVisRenderer: ( render( <> - {/* {isSplitChart && } */} + {isSplitChart && } , diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index d3bb8c1d3310e0..5d207502146011 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { CoreSetup, CoreStart } from 'src/core/public'; +import { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; @@ -42,7 +42,7 @@ export interface VisTypePiePluginStartDependencies { export interface VisTypePieDependencies { theme: ChartsPluginSetup['theme']; palettes: PaletteRegistry; - getStartDeps: () => Promise; + getStartDeps: () => Promise<{ data: DataPublicPluginStart; docLinks: DocLinksStart }>; } export class VisTypePiePlugin { @@ -52,8 +52,12 @@ export class VisTypePiePlugin { ) { if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) { const getStartDeps = async () => { - const [, deps] = await core.getStartServices(); - return deps.data; + const [coreStart, deps] = await core.getStartServices(); + // return deps.data; + return { + data: deps.data, + docLinks: coreStart.docLinks, + }; }; [createPieVisFn].forEach(expressions.registerFunction); diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.tsx similarity index 93% rename from src/plugins/vis_type_pie/public/vis_type/pie.ts rename to src/plugins/vis_type_pie/public/vis_type/pie.tsx index ada5d350a9f720..67353dd022abe1 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -16,9 +16,8 @@ * specific language governing permissions and limitations * under the License. */ - +import React from 'react'; import { i18n } from '@kbn/i18n'; -// @ts-ignore import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { Position } from '@elastic/charts'; @@ -31,6 +30,7 @@ import { PieVisParams, LabelPositions, ValueFormats } from '../types'; import { toExpressionAst } from '../to_ast'; import { getLegendPositions } from '../editor'; import { getPieOptions } from '../editor/components'; +import { SplitTooltip } from './split_tooltip'; export const getPieVisTypeDefinition = ( showElasticChartsOptions = false, @@ -103,6 +103,11 @@ export const getPieVisTypeDefinition = ( min: 0, max: 1, aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + // TODO: Remove when split chart aggs are supported + ...(showElasticChartsOptions && { + disabled: true, + tooltip: , + }), }, ]), }, diff --git a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx new file mode 100644 index 00000000000000..95006864c7e653 --- /dev/null +++ b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { FormattedMessage } from '@kbn/i18n/react'; + +export function SplitTooltip() { + return ( + + ); +} From 0d15ad904b562687cac9920a89cded3307cbd50d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 12:27:36 +0200 Subject: [PATCH 034/111] Remove temp folder --- src/plugins/charts/public/index.ts | 1 + .../public/static/components/color_picker.tsx | 19 ++- .../public/components/split_chart_warning.tsx | 48 +++--- .../vis_type_pie/public/pie_component.tsx | 8 +- .../vis_type_pie/public/pie_renderer.tsx | 34 ++-- .../public/temp/color_picker.scss | 18 --- .../vis_type_pie/public/temp/color_picker.tsx | 152 ------------------ src/plugins/vis_type_pie/public/temp/index.ts | 22 --- .../public/temp/legend_toggle.scss | 21 --- .../public/temp/legend_toggle.tsx | 62 ------- .../vis_type_pie/public/temp/lighten_color.ts | 37 ----- .../public/utils/get_color_picker.test.tsx | 2 +- .../public/utils/get_color_picker.tsx | 2 +- .../vis_type_pie/public/utils/get_layers.ts | 3 +- .../public/utils/get_legend_actions.tsx | 9 +- .../vis_type_pie/public/utils/index.ts | 2 +- .../vis_type_pie/public/vis_type/pie.tsx | 1 - 17 files changed, 65 insertions(+), 376 deletions(-) delete mode 100644 src/plugins/vis_type_pie/public/temp/color_picker.scss delete mode 100644 src/plugins/vis_type_pie/public/temp/color_picker.tsx delete mode 100644 src/plugins/vis_type_pie/public/temp/index.ts delete mode 100644 src/plugins/vis_type_pie/public/temp/legend_toggle.scss delete mode 100644 src/plugins/vis_type_pie/public/temp/legend_toggle.tsx delete mode 100644 src/plugins/vis_type_pie/public/temp/lighten_color.ts diff --git a/src/plugins/charts/public/index.ts b/src/plugins/charts/public/index.ts index 8d7cf79363dae4..3cc2f530049b79 100644 --- a/src/plugins/charts/public/index.ts +++ b/src/plugins/charts/public/index.ts @@ -25,6 +25,7 @@ export { ChartsPluginSetup, ChartsPluginStart } from './plugin'; export * from './static'; export * from './services/palettes/types'; +export { lightenColor } from './services/palettes/lighten_color'; export { PaletteOutput, CustomPaletteArguments, diff --git a/src/plugins/charts/public/static/components/color_picker.tsx b/src/plugins/charts/public/static/components/color_picker.tsx index d785a9c9ad4b78..9577020402d9eb 100644 --- a/src/plugins/charts/public/static/components/color_picker.tsx +++ b/src/plugins/charts/public/static/components/color_picker.tsx @@ -22,7 +22,7 @@ import React, { BaseSyntheticEvent } from 'react'; import { EuiButtonEmpty, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; - +import { lightenColor } from '../../services/palettes/lighten_color'; import './color_picker.scss'; export const legendColors: string[] = [ @@ -89,9 +89,18 @@ interface ColorPickerProps { label: string | number | null; onChange: (color: string | null, event: BaseSyntheticEvent) => void; color: string; + maxDepth?: number; + layerIndex?: number; } -export const ColorPicker = ({ onChange, color: selectedColor, id, label }: ColorPickerProps) => ( +export const ColorPicker = ({ + onChange, + color: selectedColor, + id, + label, + maxDepth, + layerIndex, +}: ColorPickerProps) => (
))}
- {legendColors.some((c) => c === selectedColor) && ( + {legendColors.some( + (c) => + c === selectedColor || + (layerIndex && maxDepth && lightenColor(c, layerIndex, maxDepth) === selectedColor) + ) && ( - - - - - ), - }} - /> - - + + + + + ), + }} + /> + ); } diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index d50bacd8c3cb33..920566bd2962b0 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -41,10 +41,8 @@ import { import { keys } from '@elastic/eui'; import { - // getFilterFromChartClickEventFn, - // getFilterFromSeriesFn, - // LegendToggle, - // ClickTriggerEvent, + LegendToggle, + ClickTriggerEvent, ChartsPluginSetup, PaletteRegistry, } from '../../charts/public'; @@ -56,14 +54,12 @@ import { getColorPicker, getLayers, getLegendActions, - ClickTriggerEvent, canFilter, getFilterClickData, getFilterEventData, getConfig, getColumns, } from './utils'; -import { LegendToggle } from './temp'; import './chart.scss'; diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 69d7a9baded364..9ae95b118eb858 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -19,7 +19,7 @@ import React, { lazy } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; - +import { I18nProvider } from '@kbn/i18n/react'; import { ExpressionRenderDefinition } from '../../expressions/public'; import { VisualizationContainer } from '../../visualizations/public'; import type { PersistedState } from '../../visualizations/public'; @@ -54,21 +54,23 @@ export const getPieVisRenderer: ( const services = await getStartDeps(); render( - <> - {isSplitChart && } - - - - , + + <> + {isSplitChart && } + + + + + , domNode ); }, diff --git a/src/plugins/vis_type_pie/public/temp/color_picker.scss b/src/plugins/vis_type_pie/public/temp/color_picker.scss deleted file mode 100644 index 85bfefca41a09c..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/color_picker.scss +++ /dev/null @@ -1,18 +0,0 @@ -$visColorPickerWidth: $euiSizeL * 8; // 8 columns - -.visColorPicker__value { - width: $visColorPickerWidth; -} - -.visColorPicker__valueDot { - cursor: pointer; - - &:hover { - transform: scale(1.4); - } - - &-isSelected { - border: $euiSizeXS solid; - border-radius: 100%; - } -} diff --git a/src/plugins/vis_type_pie/public/temp/color_picker.tsx b/src/plugins/vis_type_pie/public/temp/color_picker.tsx deleted file mode 100644 index e2a7bc8f6679b4..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/color_picker.tsx +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import classNames from 'classnames'; -import React, { BaseSyntheticEvent } from 'react'; - -import { EuiButtonEmpty, EuiFlexItem, EuiIcon } from '@elastic/eui'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; -import { lightenColor } from './lighten_color'; - -import './color_picker.scss'; - -export const legendColors: string[] = [ - '#3F6833', - '#967302', - '#2F575E', - '#99440A', - '#58140C', - '#052B51', - '#511749', - '#3F2B5B', - '#508642', - '#CCA300', - '#447EBC', - '#C15C17', - '#890F02', - '#0A437C', - '#6D1F62', - '#584477', - '#629E51', - '#E5AC0E', - '#64B0C8', - '#E0752D', - '#BF1B00', - '#0A50A1', - '#962D82', - '#614D93', - '#7EB26D', - '#EAB839', - '#6ED0E0', - '#EF843C', - '#E24D42', - '#1F78C1', - '#BA43A9', - '#705DA0', - '#9AC48A', - '#F2C96D', - '#65C5DB', - '#F9934E', - '#EA6460', - '#5195CE', - '#D683CE', - '#806EB7', - '#B7DBAB', - '#F4D598', - '#70DBED', - '#F9BA8F', - '#F29191', - '#82B5D8', - '#E5A8E2', - '#AEA2E0', - '#E0F9D7', - '#FCEACA', - '#CFFAFF', - '#F9E2D2', - '#FCE2DE', - '#BADFF4', - '#F9D9F9', - '#DEDAF7', -]; - -interface ColorPickerProps { - id?: string; - label: string | number | null; - onChange: (color: string | null, event: BaseSyntheticEvent) => void; - color: string; - maxDepth: number; - layerIndex: number; -} - -export const ColorPicker = ({ - onChange, - color: selectedColor, - id, - label, - maxDepth, - layerIndex, -}: ColorPickerProps) => ( - -
- - - -
- {legendColors.map((color) => ( - onChange(color, e)} - onKeyPress={(e) => onChange(color, e)} - className={classNames('visColorPicker__valueDot', { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'visColorPicker__valueDot-isSelected': color === selectedColor, - })} - style={{ color }} - data-test-subj={`visColorPickerColor-${color}`} - /> - ))} -
- {legendColors.some( - (c) => c === selectedColor || lightenColor(c, layerIndex, maxDepth) === selectedColor - ) && ( - - onChange(null, e)} - onKeyPress={(e: any) => onChange(null, e)} - > - - - - )} -
-
-); diff --git a/src/plugins/vis_type_pie/public/temp/index.ts b/src/plugins/vis_type_pie/public/temp/index.ts deleted file mode 100644 index ff6354bf92414a..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export { ColorPicker } from './color_picker'; -export { LegendToggle } from './legend_toggle'; -export { lightenColor } from './lighten_color'; diff --git a/src/plugins/vis_type_pie/public/temp/legend_toggle.scss b/src/plugins/vis_type_pie/public/temp/legend_toggle.scss deleted file mode 100644 index d372b8d9df6aa6..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/legend_toggle.scss +++ /dev/null @@ -1,21 +0,0 @@ -.echLegend__toggle { - position: absolute; - bottom: 0; - left: 0; - z-index: 1; - margin: $euiSizeXS; - - &--isOpen { - background-color: $euiColorLightestShade; - } - - &--position-left, - &--position-bottom { - left: auto; - bottom: auto; - right: 0; - top: 0; - } - } - - \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx b/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx deleted file mode 100644 index 12742b6da6e6bd..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/legend_toggle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React, { memo, useMemo } from 'react'; -import classNames from 'classnames'; - -import { i18n } from '@kbn/i18n'; -import { htmlIdGenerator, EuiButtonIcon } from '@elastic/eui'; -import { Position } from '@elastic/charts'; - -import './legend_toggle.scss'; - -interface LegendToggleProps { - onClick: () => void; - showLegend: boolean; - legendPosition: Position; -} - -const LegendToggleComponent = ({ onClick, showLegend, legendPosition }: LegendToggleProps) => { - const legendId = useMemo(() => htmlIdGenerator()('legend'), []); - - return ( - - ); -}; - -export const LegendToggle = memo(LegendToggleComponent); diff --git a/src/plugins/vis_type_pie/public/temp/lighten_color.ts b/src/plugins/vis_type_pie/public/temp/lighten_color.ts deleted file mode 100644 index 57ffb05eb5aa7d..00000000000000 --- a/src/plugins/vis_type_pie/public/temp/lighten_color.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import color from 'color'; - -const MAX_LIGHTNESS = 93; -const MAX_LIGHTNESS_SPACE = 20; - -export function lightenColor(baseColor: string, step: number, totalSteps: number) { - if (totalSteps === 1) { - return baseColor; - } - - const hslColor = color(baseColor, 'hsl'); - const outputColorLightness = hslColor.lightness(); - const lightnessSpace = Math.min(MAX_LIGHTNESS - outputColorLightness, MAX_LIGHTNESS_SPACE); - const currentLevelTargetLightness = - outputColorLightness + lightnessSpace * ((step - 1) / (totalSteps - 1)); - const lightenedColor = hslColor.lightness(currentLevelTargetLightness); - return lightenedColor.hex(); -} diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index 0b29c2b77ffd55..e42c0dc6f17aa3 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -23,7 +23,7 @@ import { mount } from 'enzyme'; import { ComponentType, ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { getColorPicker } from './get_color_picker'; -import { ColorPicker } from '../temp'; +import { ColorPicker } from '../../../charts/public'; import { createMockBucketColumns, createMockVisData } from '../mocks'; const bucketColumns = createMockBucketColumns(); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index dba5240b2048d6..c71c8409d4688e 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -22,8 +22,8 @@ import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; import { PopoverAnchorPosition, EuiPopover } from '@elastic/eui'; import { DatatableRow } from '../../../expressions/public'; +import { ColorPicker } from '../../../charts/public'; import { BucketColumns } from '../types'; -import { ColorPicker } from '../temp'; function getAnchorPosition(legendPosition: Position): PopoverAnchorPosition { switch (legendPosition) { diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 6035e1e11b546b..e8cd2a422e41fe 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -18,10 +18,9 @@ */ import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; -import { SeriesLayer, PaletteRegistry } from '../../../charts/public'; +import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public'; import { DataPublicPluginStart } from '../../../data/public'; import { BucketColumns, PieVisParams } from '../types'; -import { lightenColor } from '../temp'; const EMPTY_SLICE = Symbol('empty_slice'); diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 2596c1090c0241..3d4b565fbcac26 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -22,16 +22,9 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; import { LegendAction, SeriesIdentifier } from '@elastic/charts'; -import { ValueClickContext } from '../../../embeddable/public'; import { DataPublicPluginStart } from '../../../data/public'; import { PieVisParams } from '../types'; -// import { ClickTriggerEvent } from '../../../charts/public'; - -// this is temporary -export interface ClickTriggerEvent { - name: 'filterBucket'; - data: ValueClickContext['data']; -} +import { ClickTriggerEvent } from '../../../charts/public'; export const getLegendActions = ( canFilter: ( diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index d23cea793dcc5d..52f70fab1bdbcf 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -19,7 +19,7 @@ export { getLayers } from './get_layers'; export { getColorPicker } from './get_color_picker'; -export { getLegendActions, ClickTriggerEvent } from './get_legend_actions'; +export { getLegendActions } from './get_legend_actions'; export { canFilter, getFilterClickData, getFilterEventData } from './filter_helpers'; export { getConfig } from './get_config'; export { getColumns } from './get_columns'; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index 67353dd022abe1..b1bcf97aeea23e 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -18,7 +18,6 @@ */ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { Position } from '@elastic/charts'; import { Schemas } from '../../../vis_default_editor/public'; From 00069dd22ffe807f2676fafcab37fd373b2d695f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 14:01:05 +0200 Subject: [PATCH 035/111] Move translations to the pie plugin --- .../translations/translations/ja-JP.json | 20 +++++++++---------- .../translations/translations/zh-CN.json | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index e5b82a5d3fcbc7..81ae37b69a6af3 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4397,12 +4397,12 @@ "visTypeVislib.editors.heatmap.heatmapSettingsTitle": "ヒートマップ設定", "visTypeVislib.editors.heatmap.highlightLabel": "ハイライト範囲", "visTypeVislib.editors.heatmap.highlightLabelTooltip": "チャートのカーソルを当てた部分と凡例の対応するラベルをハイライトします。", - "visTypeVislib.editors.pie.donutLabel": "ドーナッツ", - "visTypeVislib.editors.pie.labelsSettingsTitle": "ラベル設定", - "visTypeVislib.editors.pie.pieSettingsTitle": "パイ設定", - "visTypeVislib.editors.pie.showLabelsLabel": "ラベルを表示", - "visTypeVislib.editors.pie.showTopLevelOnlyLabel": "トップレベルのみ表示", - "visTypeVislib.editors.pie.showValuesLabel": "値を表示", + "visTypePie.editors.pie.donutLabel": "ドーナッツ", + "visTypePie.editors.pie.labelsSettingsTitle": "ラベル設定", + "visTypePie.editors.pie.pieSettingsTitle": "パイ設定", + "visTypePie.editors.pie.showLabelsLabel": "ラベルを表示", + "visTypePie.editors.pie.showTopLevelOnlyLabel": "トップレベルのみ表示", + "visTypePie.editors.pie.showValuesLabel": "値を表示", "visTypeXy.editors.pointSeries.currentTimeMarkerLabel": "現在時刻マーカー", "visTypeXy.editors.pointSeries.orderBucketsBySumLabel": "バケットを合計で並べ替え", "visTypeXy.editors.pointSeries.settingsTitle": "設定", @@ -4453,10 +4453,10 @@ "visTypeXy.line.radiusTitle": "点のサイズ", "visTypeXy.line.segmentTitle": "X 軸", "visTypeXy.line.splitTitle": "チャートを分割", - "visTypeVislib.pie.metricTitle": "サイズのスライス", - "visTypeVislib.pie.pieTitle": "パイ", - "visTypeVislib.pie.segmentTitle": "スライスの分割", - "visTypeVislib.pie.splitTitle": "チャートを分割", + "visTypePie.pie.metricTitle": "サイズのスライス", + "visTypePie.pie.pieTitle": "パイ", + "visTypePie.pie.segmentTitle": "スライスの分割", + "visTypePie.pie.splitTitle": "チャートを分割", "visTypeXy.scaleTypes.linearText": "線形", "visTypeXy.scaleTypes.logText": "ログ", "visTypeXy.scaleTypes.squareRootText": "平方根", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 879418870b527f..d75e18b8d33464 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4399,12 +4399,12 @@ "visTypeVislib.editors.heatmap.heatmapSettingsTitle": "热图设置", "visTypeVislib.editors.heatmap.highlightLabel": "高亮范围", "visTypeVislib.editors.heatmap.highlightLabelTooltip": "高亮显示图表中鼠标悬停的范围以及图例中对应的标签。", - "visTypeVislib.editors.pie.donutLabel": "圆环图", - "visTypeVislib.editors.pie.labelsSettingsTitle": "标签设置", - "visTypeVislib.editors.pie.pieSettingsTitle": "饼图设置", - "visTypeVislib.editors.pie.showLabelsLabel": "显示标签", - "visTypeVislib.editors.pie.showTopLevelOnlyLabel": "仅显示顶级", - "visTypeVislib.editors.pie.showValuesLabel": "显示值", + "visTypePie.editors.pie.donutLabel": "圆环图", + "visTypePie.editors.pie.labelsSettingsTitle": "标签设置", + "visTypePie.editors.pie.pieSettingsTitle": "饼图设置", + "visTypePie.editors.pie.showLabelsLabel": "显示标签", + "visTypePie.editors.pie.showTopLevelOnlyLabel": "仅显示顶级", + "visTypePie.editors.pie.showValuesLabel": "显示值", "visTypeXy.editors.pointSeries.currentTimeMarkerLabel": "当前时间标记", "visTypeXy.editors.pointSeries.orderBucketsBySumLabel": "按总计值排序存储桶", "visTypeXy.editors.pointSeries.settingsTitle": "设置", @@ -4455,10 +4455,10 @@ "visTypeXy.line.radiusTitle": "点大小", "visTypeXy.line.segmentTitle": "X 轴", "visTypeXy.line.splitTitle": "拆分图表", - "visTypeVislib.pie.metricTitle": "切片大小", - "visTypeVislib.pie.pieTitle": "饼图", - "visTypeVislib.pie.segmentTitle": "拆分切片", - "visTypeVislib.pie.splitTitle": "拆分图表", + "visTypePie.pie.metricTitle": "切片大小", + "visTypePie.pie.pieTitle": "饼图", + "visTypePie.pie.segmentTitle": "拆分切片", + "visTypePie.pie.splitTitle": "拆分图表", "visTypeXy.scaleTypes.linearText": "线性", "visTypeXy.scaleTypes.logText": "对数", "visTypeXy.scaleTypes.squareRootText": "平方根", From 425d7c4db3fb079f7986a83f7b7a307449a7a95e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 15:15:44 +0200 Subject: [PATCH 036/111] Fix CI failures --- .../public/static/components/color_picker.tsx | 2 +- .../public/utils/filter_helpers.ts | 2 +- .../visualization_migrations.test.ts | 51 ++------------ .../saved_objects/visualization_migrations.ts | 66 +++++++++---------- 4 files changed, 40 insertions(+), 81 deletions(-) diff --git a/src/plugins/charts/public/static/components/color_picker.tsx b/src/plugins/charts/public/static/components/color_picker.tsx index 9577020402d9eb..ddbb9605efef55 100644 --- a/src/plugins/charts/public/static/components/color_picker.tsx +++ b/src/plugins/charts/public/static/components/color_picker.tsx @@ -101,7 +101,7 @@ export const ColorPicker = ({ maxDepth, layerIndex, }: ColorPickerProps) => ( -
+
{ }); }); - describe('7.12.0 update vislib pie defaults', () => { - const migrate = (doc: any) => - visualizationSavedObjectTypeMigrations['7.12.0']( - doc as Parameters[0], - savedObjectMigrationContext - ); - const generateDoc = (type = 'pie') => ({ - attributes: { - type, - title: 'My Vis', - description: 'This is my super cool vis.', - visState: JSON.stringify({ - type, - title: 'My pie vis', - params: { - type, - addLegend: true, - addTooltip: true, - isDonut: true, - labels: { - show: true, - truncate: 100, - }, - }, - }), - }, - }); - - it('should return original doc if is not a pie chart', () => { - const doc = generateDoc('area'); - const migratedTestDoc = migrate(doc); - expect(migratedTestDoc).toEqual(doc); - }); - - it('should decorate existing docs with the kibana legacy palette', () => { - const migratedTestDoc = migrate(generateDoc()); - const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; - - expect(palette.name).toEqual('kibana_palette'); - }); - }); - describe('7.12.0 update vislib visualization defaults', () => { const migrate = (doc: any) => visualizationSavedObjectTypeMigrations['7.12.0']( @@ -1749,10 +1707,11 @@ describe('migration visualization', () => { }, }); - it('should return original doc if not area, line or histogram chart', () => { - const doc = getTestDoc('pie'); - const migratedTestDoc = migrate(doc); - expect(migratedTestDoc).toEqual(doc); + it('should decorate existing docs with the kibana legacy palette', () => { + const migratedTestDoc = migrate(getTestDoc('pie')); + const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(palette.name).toEqual('kibana_palette'); }); it('should decorate existing docs with isVislibVis flag', () => { diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 6afd0a14f27ed2..45e9bb27c60575 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -760,39 +760,6 @@ const removeTSVBSearchSource: SavedObjectMigrationFn = (doc) => { return doc; }; -// [Pie Chart] Migrate vislib pie chart to use the new plugin vis_type_pie -const migrateVislibPie: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); - let visState; - - if (visStateJSON) { - try { - visState = JSON.parse(visStateJSON); - } catch (e) { - // Let it go, the data is invalid and we'll leave it as is - } - if (visState && visState.type === 'pie') { - return { - ...doc, - attributes: { - ...doc.attributes, - visState: JSON.stringify({ - ...visState, - params: { - ...visState.params, - palette: { - type: 'palette', - name: 'kibana_palette', - }, - }, - }), - }, - }; - } - } - return doc; -}; - // [Data table visualization] Enable toolbar by default const enableDataTableVisToolbar: SavedObjectMigrationFn = (doc) => { let visState; @@ -885,6 +852,39 @@ const migrateVislibAreaLineBarTypes: SavedObjectMigrationFn = (doc) => return doc; }; +// [Pie Chart] Migrate vislib pie chart to use the new plugin vis_type_pie +const migrateVislibPie: SavedObjectMigrationFn = (doc) => { + const visStateJSON = get(doc, 'attributes.visState'); + let visState; + + if (visStateJSON) { + try { + visState = JSON.parse(visStateJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + } + if (visState && visState.type === 'pie') { + return { + ...doc, + attributes: { + ...doc.attributes, + visState: JSON.stringify({ + ...visState, + params: { + ...visState.params, + palette: { + type: 'palette', + name: 'kibana_palette', + }, + }, + }), + }, + }; + } + } + return doc; +}; + export const visualizationSavedObjectTypeMigrations = { /** * We need to have this migration twice, once with a version prior to 7.0.0 once with a version From bfc3b1b933e464147959bc95e5c48cd2f38fa6d3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 16:00:04 +0200 Subject: [PATCH 037/111] Add unit test for the editor config --- .../public/editor/components/pie.test.tsx | 124 ++++++++++++++++++ .../public/editor/components/pie.tsx | 6 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/plugins/vis_type_pie/public/editor/components/pie.test.tsx diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx new file mode 100644 index 00000000000000..a1f52c41635f31 --- /dev/null +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -0,0 +1,124 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { mountWithIntl } from '@kbn/test/jest'; +import { ReactWrapper } from 'enzyme'; +import PieOptions, { PieOptionsProps } from './pie'; +import { chartPluginMock } from '../../../../charts/public/mocks'; +import { findTestSubject } from '@elastic/eui/lib/test'; + +jest.mock('../collections', () => ({ + getLabelPositions: jest.fn(() => []), + getValuesFormats: jest.fn(() => []), +})); + +describe('PalettePicker', function () { + let props: PieOptionsProps; + let component: ReactWrapper; + + beforeAll(() => { + props = ({ + palettes: chartPluginMock.createPaletteRegistry(), + showElasticChartsOptions: true, + vis: { + type: { + editorConfig: { + collections: { + legendPositions: [ + { + text: 'Top', + value: 'top', + }, + { + text: 'Left', + value: 'left', + }, + { + text: 'Right', + value: 'right', + }, + { + text: 'Bottom', + value: 'bottom', + }, + ], + }, + }, + }, + }, + stateParams: { + isDonut: true, + legendPosition: 'left', + labels: { + show: true, + }, + }, + } as unknown) as PieOptionsProps; + }); + + it('renders the nested legend switch for the elastic charts implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(1); + }); + + it('not renders the nested legend switch for the vislib implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(0); + }); + + it('renders the palettes picker for the elastic charts implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'piePalettePicker').length).toBe(1); + }); + + it('not renders the palettes picker for the vislib implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'piePalettePicker').length).toBe(0); + }); + + it('renders the label position dropdown for the elastic charts implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(1); + }); + + it('not renders the label position dropdown for the vislib implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(0); + }); + + it('not renders the top level switch for the elastic charts implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(0); + }); + + it('renders the top level switch for the vislib implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(1); + }); + + it('renders the value format dropdown for the elastic charts implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(1); + }); + + it('not renders the value format dropdown for the vislib implementation', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(0); + }); +}); diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index a9edfc001bf175..3dc316bf893f32 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -34,7 +34,7 @@ import { import { PieVisParams, LabelPositions, ValueFormats } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; -interface PieOptionsProps extends VisOptionsProps { +export interface PieOptionsProps extends VisOptionsProps { palettes: PaletteRegistry | undefined; showElasticChartsOptions: boolean; } @@ -75,6 +75,7 @@ const PieOptions = (props: PieOptionsProps) => { paramName="nestedLegend" value={stateParams.nestedLegend} setValue={setValue} + data-test-subj="visTypePieNestedLegendSwitch" /> )} {props.showElasticChartsOptions && props.palettes && ( @@ -117,6 +118,7 @@ const PieOptions = (props: PieOptionsProps) => { paramName="position" value={stateParams.labels.position || LabelPositions.DEFAULT} setValue={setLabels} + data-test-subj="visTypePieLabelPositionSelect" /> )} {!props.showElasticChartsOptions && ( @@ -127,6 +129,7 @@ const PieOptions = (props: PieOptionsProps) => { paramName="last_level" value={stateParams.labels.last_level} setValue={setLabels} + data-test-subj="visTypePieTopLevelSwitch" /> )} { paramName="valuesFormat" value={stateParams.labels.valuesFormat || ValueFormats.PERCENT} setValue={setLabels} + data-test-subj="visTypePieValueFormatsSelect" /> )} From b3efd327e5ce0c2f8b25a7744043eb78557ccff5 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 17:16:42 +0200 Subject: [PATCH 038/111] Types cleanup --- src/plugins/vis_type_pie/public/index.ts | 1 + .../vis_type_pie/public/types/index.ts | 2 +- .../public/types/{params.ts => types.ts} | 34 ++----------------- .../build_hierarchical_data.test.ts | 4 +-- .../hierarchical/build_hierarchical_data.ts | 17 +--------- 5 files changed, 8 insertions(+), 50 deletions(-) rename src/plugins/vis_type_pie/public/types/{params.ts => types.ts} (73%) diff --git a/src/plugins/vis_type_pie/public/index.ts b/src/plugins/vis_type_pie/public/index.ts index 91528f8ff339c2..2ed826079daf06 100644 --- a/src/plugins/vis_type_pie/public/index.ts +++ b/src/plugins/vis_type_pie/public/index.ts @@ -19,5 +19,6 @@ import { VisTypePiePlugin } from './plugin'; export { pieVisType } from './vis_type'; +export { Dimensions, Dimension } from './types'; export const plugin = () => new VisTypePiePlugin(); diff --git a/src/plugins/vis_type_pie/public/types/index.ts b/src/plugins/vis_type_pie/public/types/index.ts index f0cbe26b3fced0..2b3cf56a1f6611 100644 --- a/src/plugins/vis_type_pie/public/types/index.ts +++ b/src/plugins/vis_type_pie/public/types/index.ts @@ -16,4 +16,4 @@ * specific language governing permissions and limitations * under the License. */ -export * from './params'; +export * from './types'; diff --git a/src/plugins/vis_type_pie/public/types/params.ts b/src/plugins/vis_type_pie/public/types/types.ts similarity index 73% rename from src/plugins/vis_type_pie/public/types/params.ts rename to src/plugins/vis_type_pie/public/types/types.ts index 4308fe21d61bba..30940ccc3c9a6b 100644 --- a/src/plugins/vis_type_pie/public/types/params.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -17,14 +17,14 @@ * under the License. */ import { Position } from '@elastic/charts'; -import { DatatableColumn } from '../../../expressions/public'; +import { DatatableColumn, SerializedFieldFormat } from '../../../expressions/public'; import { PaletteOutput } from '../../../charts/public'; export interface Dimension { accessor: number; format: { id?: string; - params?: { pattern?: string; [key: string]: any }; + params?: SerializedFieldFormat; }; } @@ -54,41 +54,13 @@ export interface PieVisParams { }; } -export interface Column { - // -1 value can be in a fake X aspect - id: string | -1; - name: string; -} - -export interface Row { - [key: string]: number | string | object; -} - -export interface TableParent { - table: Table; - tables?: Table[]; - column: number; - row: number; - key: number; - name: string; -} -export interface Table { - columns: Column[]; - rows: Row[]; - $parent?: TableParent; -} - export interface BucketColumns extends DatatableColumn { format?: { id?: string; - params?: { pattern?: string; [key: string]: any }; + params?: SerializedFieldFormat; }; } -export interface EmptyBucket { - name: string; -} - export enum LabelPositions { INSIDE = 'inside', DEFAULT = 'default', diff --git a/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.test.ts b/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.test.ts index 7cef113ffc3498..d3101053b74bba 100644 --- a/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.test.ts +++ b/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.test.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ - -import { buildHierarchicalData, Dimensions, Dimension } from './build_hierarchical_data'; +import type { Dimensions, Dimension } from '../../../../../vis_type_pie/public'; +import { buildHierarchicalData } from './build_hierarchical_data'; import { Table, TableParent } from '../../types'; function tableVisResponseHandler(table: Table, dimensions: Dimensions) { diff --git a/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.ts b/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.ts index 3bc8fa0f035b68..157be8f1b6977d 100644 --- a/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.ts +++ b/src/plugins/vis_type_vislib/public/vislib/helpers/hierarchical/build_hierarchical_data.ts @@ -18,24 +18,9 @@ */ import { toArray } from 'lodash'; -import { SerializedFieldFormat } from '../../../../../expressions/common/types'; import { getFormatService } from '../../../services'; import { Table } from '../../types'; - -export interface Dimension { - accessor: number; - format: { - id?: string; - params?: SerializedFieldFormat; - }; -} - -export interface Dimensions { - metric: Dimension; - buckets?: Dimension[]; - splitRow?: Dimension[]; - splitColumn?: Dimension[]; -} +import type { Dimensions } from '../../../../../vis_type_pie/public'; interface Slice { name: string; From ab268f254f03eecd82bc35bdbe4f88932505a129 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 21 Dec 2020 17:43:47 +0200 Subject: [PATCH 039/111] Fix types vol2 --- src/plugins/vis_type_pie/public/mocks.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts index 9e46e05b0857a4..2c0c65d7439ac7 100644 --- a/src/plugins/vis_type_pie/public/mocks.ts +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -59,8 +59,6 @@ export const createMockBucketColumns = (): BucketColumns[] => { id: 'terms', params: { id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', }, }, }, @@ -102,8 +100,6 @@ export const createMockBucketColumns = (): BucketColumns[] => { id: 'terms', params: { id: 'boolean', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', }, }, }, From efa5628b7939161ef57f002a6286a9f7e6330daf Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 22 Dec 2020 10:50:16 +0200 Subject: [PATCH 040/111] Minor improvements --- docs/developer/plugin-list.asciidoc | 2 +- src/plugins/vis_type_pie/README.md | 2 +- .../vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap | 4 ++++ src/plugins/vis_type_pie/public/pie_fn.test.ts | 4 ++++ src/plugins/vis_type_pie/public/plugin.ts | 1 - src/plugins/vis_type_pie/public/utils/get_columns.test.ts | 2 +- 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index e086bb26416b16..1edd27469f9eb5 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -246,7 +246,7 @@ The plugin exposes the static DefaultEditorController class to consume. |{kib-repo}blob/{branch}/src/plugins/vis_type_pie/README.md[visTypePie] -|Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Charts Library advanced setting. +|Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Legacy charts library advanced setting. |{kib-repo}blob/{branch}/src/plugins/vis_type_table/README.md[visTypeTable] diff --git a/src/plugins/vis_type_pie/README.md b/src/plugins/vis_type_pie/README.md index 0744c9aa3a44c7..41b8131a5381d0 100644 --- a/src/plugins/vis_type_pie/README.md +++ b/src/plugins/vis_type_pie/README.md @@ -1 +1 @@ -Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Charts Library advanced setting. \ No newline at end of file +Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Legacy charts library advanced setting. \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 8f39e4ce5af424..66b34b6c211190 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -24,11 +24,15 @@ Object { "isDonut": true, "labels": Object { "last_level": true, + "position": "default", "show": false, "truncate": 100, "values": true, + "valuesFormat": "percent", }, "legendPosition": "right", + "nestedLegend": true, + "palette": "kibana_palette", "type": "pie", }, "visData": Object { diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index d7dab8ca6de12f..efa3551a8baa2d 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -33,10 +33,14 @@ describe('interpreter/functions#pie', () => { addLegend: true, legendPosition: 'right', isDonut: true, + nestedLegend: true, + palette: 'kibana_palette', labels: { show: false, values: true, last_level: true, + position: 'default', + valuesFormat: 'percent', truncate: 100, }, dimensions: { diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 5d207502146011..10ca9e1d52f339 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -53,7 +53,6 @@ export class VisTypePiePlugin { if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) { const getStartDeps = async () => { const [coreStart, deps] = await core.getStartServices(); - // return deps.data; return { data: deps.data, docLinks: coreStart.docLinks, diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index 4bd375136b8165..9eefa5895e2901 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -163,7 +163,7 @@ describe('getColumns', () => { expect(metricColumn).toEqual(visData.columns[0]); }); - it('should return anwith the name of the metric if no buckets specified', () => { + it('should return an object with the name of the metric if no buckets specified', () => { const visParamsNoDimensions = ({ addLegend: true, addTooltip: true, From 3257bb95f358e00153e2a9f8c14beeaea943e8da Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 22 Dec 2020 11:49:10 +0200 Subject: [PATCH 041/111] Display data on the inspector --- src/plugins/vis_type_pie/public/pie_fn.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 6123a2e7d32463..e3236a471ac6ae 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -54,9 +54,13 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ help: 'vislib pie vis config', }, }, - fn(context, args) { + fn(context, args, handlers) { const visConfig = JSON.parse(args.visConfig) as PieVisParams; + if (handlers?.inspectorAdapters?.tables) { + handlers.inspectorAdapters.tables.logDatatable('default', context); + } + return { type: 'render', as: vislibPieName, From 9c37f8fd0dd6da56433f11568379439a1c6ad438 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 24 Dec 2020 09:49:33 +0200 Subject: [PATCH 042/111] Cleanup translations --- x-pack/plugins/translations/translations/ja-JP.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d99cd45e369ee4..2f3cb49967d911 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4335,12 +4335,6 @@ "visTypeVislib.editors.heatmap.heatmapSettingsTitle": "ヒートマップ設定", "visTypeVislib.editors.heatmap.highlightLabel": "ハイライト範囲", "visTypeVislib.editors.heatmap.highlightLabelTooltip": "チャートのカーソルを当てた部分と凡例の対応するラベルをハイライトします。", - "visTypeVislib.editors.pie.donutLabel": "ドーナッツ", - "visTypeVislib.editors.pie.labelsSettingsTitle": "ラベル設定", - "visTypeVislib.editors.pie.pieSettingsTitle": "パイ設定", - "visTypeVislib.editors.pie.showLabelsLabel": "ラベルを表示", - "visTypeVislib.editors.pie.showTopLevelOnlyLabel": "トップレベルのみ表示", - "visTypeVislib.editors.pie.showValuesLabel": "値を表示", "visTypeVislib.functions.pie.help": "パイビジュアライゼーション", "visTypeVislib.functions.vislib.help": "Vislib ビジュアライゼーション", "visTypeVislib.gauge.alignmentAutomaticTitle": "自動", From a681c4c2796b8d6a3fb2896248c09e073e04dce6 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 24 Dec 2020 11:35:19 +0200 Subject: [PATCH 043/111] Add telemetry for new editor pie options --- src/plugins/vis_type_pie/kibana.json | 2 +- .../public/editor/components/index.tsx | 6 ++-- .../public/editor/components/pie.tsx | 31 ++++++++++++++++--- src/plugins/vis_type_pie/public/plugin.ts | 9 ++++-- .../vis_type_pie/public/vis_type/index.ts | 9 ++++-- .../vis_type_pie/public/vis_type/pie.tsx | 7 +++-- 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_pie/kibana.json b/src/plugins/vis_type_pie/kibana.json index bbefe784fd6850..c2d51fba8260dd 100644 --- a/src/plugins/vis_type_pie/kibana.json +++ b/src/plugins/vis_type_pie/kibana.json @@ -2,7 +2,7 @@ "id": "visTypePie", "version": "kibana", "ui": true, - "requiredPlugins": ["charts", "data", "expressions", "visualizations"], + "requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"], "requiredBundles": ["visDefaultEditor"] } \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index f69a42ebec93c7..d806ff7a5444d2 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - +import { UiCounterMetricType } from '@kbn/analytics'; import React, { lazy } from 'react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { PaletteRegistry } from 'src/plugins/charts/public'; @@ -26,11 +26,13 @@ const PieOptionsLazy = lazy(() => import('./pie')); export const getPieOptions = ( palettes: PaletteRegistry | undefined, - showElasticChartsOptions: boolean + showElasticChartsOptions: boolean, + trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void ) => (props: VisOptionsProps) => ( ); diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index b91a26ebdb83c9..0ad9942c2ffc10 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; - +import { UiCounterMetricType, METRIC_TYPE } from '@kbn/analytics'; import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -37,6 +37,7 @@ import { getLabelPositions, getValuesFormats } from '../collections'; export interface PieOptionsProps extends VisOptionsProps { palettes: PaletteRegistry | undefined; showElasticChartsOptions: boolean; + trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; } const PieOptions = (props: PieOptionsProps) => { @@ -74,7 +75,12 @@ const PieOptions = (props: PieOptionsProps) => { })} paramName="nestedLegend" value={stateParams.nestedLegend} - setValue={setValue} + setValue={(paramName, value) => { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'nested_legend_switched'); + } + setValue(paramName, value); + }} data-test-subj="visTypePieNestedLegendSwitch" /> )} @@ -83,7 +89,12 @@ const PieOptions = (props: PieOptionsProps) => { palettes={props.palettes} activePalette={stateParams.palette} paramName="palette" - setPalette={setValue} + setPalette={(paramName, value) => { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'palette_selected'); + } + setValue(paramName, value); + }} /> )} @@ -117,7 +128,12 @@ const PieOptions = (props: PieOptionsProps) => { options={getLabelPositions()} paramName="position" value={stateParams.labels.position || LabelPositions.DEFAULT} - setValue={setLabels} + setValue={(paramName, value) => { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'label_position_selected'); + } + setLabels(paramName, value); + }} data-test-subj="visTypePieLabelPositionSelect" /> )} @@ -149,7 +165,12 @@ const PieOptions = (props: PieOptionsProps) => { options={getValuesFormats()} paramName="valuesFormat" value={stateParams.labels.valuesFormat || ValueFormats.PERCENT} - setValue={setLabels} + setValue={(paramName, value) => { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'values_format_selected'); + } + setLabels(paramName, value); + }} data-test-subj="visTypePieValueFormatsSelect" /> )} diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 10ca9e1d52f339..5c52f803949051 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -20,6 +20,7 @@ import { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; +import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; import { LEGACY_CHARTS_LIBRARY } from '../common'; import { createPieVisFn } from './pie_fn'; @@ -31,6 +32,7 @@ export interface VisTypePieSetupDependencies { visualizations: VisualizationsSetup; expressions: ReturnType; charts: ChartsPluginSetup; + usageCollection: UsageCollectionSetup; } /** @internal */ @@ -48,9 +50,9 @@ export interface VisTypePieDependencies { export class VisTypePiePlugin { setup( core: CoreSetup, - { expressions, visualizations, charts }: VisTypePieSetupDependencies + { expressions, visualizations, charts, usageCollection }: VisTypePieSetupDependencies ) { - if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) { + if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, false)) { const getStartDeps = async () => { const [coreStart, deps] = await core.getStartServices(); return { @@ -58,13 +60,14 @@ export class VisTypePiePlugin { docLinks: coreStart.docLinks, }; }; + const trackUiMetric = usageCollection?.reportUiCounter.bind(usageCollection, 'vis_type_pie'); [createPieVisFn].forEach(expressions.registerFunction); charts.palettes.getPalettes().then((palettes) => { expressions.registerRenderer( getPieVisRenderer({ theme: charts.theme, palettes, getStartDeps }) ); - visualizations.createBaseVisualization(pieVisType(true, palettes)); + visualizations.createBaseVisualization(pieVisType(true, palettes, trackUiMetric)); }); } return {}; diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index ab191542d0d498..9b1d41fa5b4442 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -16,9 +16,14 @@ * specific language governing permissions and limitations * under the License. */ +import { UiCounterMetricType } from '@kbn/analytics'; import { PaletteRegistry } from '../../../charts/public'; import { getPieVisTypeDefinition } from './pie'; -export const pieVisType = (showElasticChartsOptions?: boolean, palettes?: PaletteRegistry) => { - return getPieVisTypeDefinition(showElasticChartsOptions, palettes); +export const pieVisType = ( + showElasticChartsOptions?: boolean, + palettes?: PaletteRegistry, + trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void +) => { + return getPieVisTypeDefinition(showElasticChartsOptions, palettes, trackUiMetric); }; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index b1bcf97aeea23e..70689a8a56c247 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; - +import { UiCounterMetricType } from '@kbn/analytics'; import { Schemas } from '../../../vis_default_editor/public'; import { AggGroupNames } from '../../../data/public'; import { PaletteRegistry } from '../../../charts/public'; @@ -33,7 +33,8 @@ import { SplitTooltip } from './split_tooltip'; export const getPieVisTypeDefinition = ( showElasticChartsOptions = false, - palettes: PaletteRegistry | undefined + palettes: PaletteRegistry | undefined, + trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void ): BaseVisTypeOptions => ({ name: 'pie', title: i18n.translate('visTypePie.pie.pieTitle', { defaultMessage: 'Pie' }), @@ -69,7 +70,7 @@ export const getPieVisTypeDefinition = ( collections: { legendPositions: getLegendPositions(), }, - optionsTemplate: getPieOptions(palettes, showElasticChartsOptions), + optionsTemplate: getPieOptions(palettes, showElasticChartsOptions, trackUiMetric), schemas: new Schemas([ { group: AggGroupNames.Metrics, From ed95218f9df1c052acc38d6e4ed12cb682fee547 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 11 Jan 2021 10:46:26 +0200 Subject: [PATCH 044/111] Fix missing translation --- x-pack/plugins/translations/translations/ja-JP.json | 2 +- x-pack/plugins/translations/translations/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 837522a72d1867..a71882754d88e5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4662,7 +4662,7 @@ "visTypeVislib.heatmap.segmentTitle": "X 軸", "visTypeVislib.heatmap.splitTitle": "チャートを分割", "visTypePie.pie.metricTitle": "スライスサイズ", - "visTypeVislib.pie.pieDescription": "全体に対する比率でデータを比較します。", + "visTypePie.pie.pieDescription": "全体に対する比率でデータを比較します。", "visTypePie.pie.pieTitle": "円", "visTypePie.pie.segmentTitle": "スライスの分割", "visTypePie.pie.splitTitle": "チャートを分割", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6d7d41b8c8a387..a4fed0a3987191 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4667,7 +4667,7 @@ "visTypeVislib.heatmap.segmentTitle": "X 轴", "visTypeVislib.heatmap.splitTitle": "拆分图表", "visTypePie.pie.metricTitle": "切片大小", - "visTypeVislib.pie.pieDescription": "以整体的比例比较数据。", + "visTypePie.pie.pieDescription": "以整体的比例比较数据。", "visTypePie.pie.pieTitle": "饼图", "visTypePie.pie.segmentTitle": "拆分切片", "visTypePie.pie.splitTitle": "拆分图表", From e64bc3486475dd677f63e9e081f98f20f11819de Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 13 Jan 2021 11:52:57 +0200 Subject: [PATCH 045/111] Use Eui component to detect click outside the color picker popover --- .../public/utils/get_color_picker.tsx | 60 ++++++++----------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index c71c8409d4688e..d15a85e474a72c 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -17,10 +17,10 @@ * under the License. */ -import React, { BaseSyntheticEvent, useRef, useEffect, useCallback } from 'react'; +import React, { BaseSyntheticEvent, useCallback } from 'react'; import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; -import { PopoverAnchorPosition, EuiPopover } from '@elastic/eui'; +import { PopoverAnchorPosition, EuiPopover, EuiOutsideClickDetector } from '@elastic/eui'; import { DatatableRow } from '../../../expressions/public'; import { ColorPicker } from '../../../charts/public'; import { BucketColumns } from '../types'; @@ -67,7 +67,6 @@ export const getColorPicker = ( palette: string, data: DatatableRow[] ): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { - const ref = useRef(null); const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { if (newColor) { @@ -77,21 +76,9 @@ export const getColorPicker = ( onClose(); }; - const handleOutsideClick = useCallback( - (e: MouseEvent) => { - if (ref.current && !(ref.current! as any).contains(e.target)) { - onClose?.(); - } - }, - [onClose] - ); - - useEffect(() => { - document.addEventListener('click', handleOutsideClick); - return () => { - document.removeEventListener('click', handleOutsideClick); - }; - }, [handleOutsideClick]); + const handleOutsideClick = useCallback(() => { + onClose?.(); + }, [onClose]); // For the EuiPalette we want the user to be able to change only the colors of the inner layer if (palette !== 'kibana_palette') { @@ -100,23 +87,24 @@ export const getColorPicker = ( } const hexColor = new Color(color).hex(); return ( - - - + + + + + ); }; From 2072459a445422fc0fe9a0110a11c90efdc90910 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 13 Jan 2021 16:41:22 +0200 Subject: [PATCH 046/111] Retrieve color picker from editor and syncColors on dashboard --- .../editor/components/palette_picker.test.tsx | 59 --------------- .../editor/components/palette_picker.tsx | 74 ------------------- .../public/editor/components/pie.tsx | 2 +- .../vis_type_pie/public/pie_component.tsx | 16 +++- src/plugins/vis_type_pie/public/pie_fn.ts | 2 + .../vis_type_pie/public/pie_renderer.tsx | 3 +- .../vis_type_pie/public/utils/get_layers.ts | 4 +- .../visualization_migrations.test.ts | 4 +- 8 files changed, 23 insertions(+), 141 deletions(-) delete mode 100644 src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx delete mode 100644 src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx deleted file mode 100644 index 1b4d7e060296ae..00000000000000 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.test.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import React from 'react'; -import { mountWithIntl } from '@kbn/test/jest'; -import { ReactWrapper } from 'enzyme'; -import { PalettePicker, PalettePickerProps } from './palette_picker'; -import { chartPluginMock } from '../../../../charts/public/mocks'; -import { EuiColorPalettePicker } from '@elastic/eui'; - -describe('PalettePicker', function () { - let props: PalettePickerProps<'palette'>; - let component: ReactWrapper>; - - beforeAll(() => { - props = { - palettes: chartPluginMock.createPaletteRegistry(), - paramName: 'palette', - activePalette: { - type: 'palette', - name: 'kibana_palette', - }, - setPalette: jest.fn(), - }; - }); - - it('renders the EuiPalettePicker', () => { - component = mountWithIntl(); - expect(component.find(EuiColorPalettePicker).length).toBe(1); - }); - - it('renders the default palette if not activePalette is given', function () { - const { activePalette, ...newProps } = props; - component = mountWithIntl(); - const palettePicker = component.find(EuiColorPalettePicker); - expect(palettePicker.props().valueOfSelected).toBe('default'); - }); - - it('renders the activePalette palette if given', function () { - component = mountWithIntl(); - const palettePicker = component.find(EuiColorPalettePicker); - expect(palettePicker.props().valueOfSelected).toBe('kibana_palette'); - }); -}); diff --git a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx b/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx deleted file mode 100644 index 1e7088581c0f53..00000000000000 --- a/src/plugins/vis_type_pie/public/editor/components/palette_picker.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; -import { EuiColorPalettePicker } from '@elastic/eui'; -import { EuiFormRow } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export interface PalettePickerProps { - activePalette?: PaletteOutput; - palettes: PaletteRegistry; - paramName: ParamName; - setPalette: (paramName: ParamName, value: PaletteOutput) => void; -} - -export function PalettePicker({ - activePalette, - palettes, - paramName, - setPalette, -}: PalettePickerProps) { - return ( - - !internal) - .map(({ id, title, getColors }) => { - return { - value: id, - title, - type: 'fixed', - palette: getColors( - 10, - id === activePalette?.name ? activePalette?.params : undefined - ), - }; - })} - onChange={(newPalette) => { - setPalette(paramName, { - type: 'palette', - name: newPalette, - }); - }} - valueOfSelected={activePalette?.name || 'default'} - selectionDisplay={'palette'} - /> - - ); -} diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 0ad9942c2ffc10..c5009df6f95eb8 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -27,9 +27,9 @@ import { BasicOptions, SwitchOption, SelectOption, + PalettePicker, } from '../../../../vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; -import { PalettePicker } from './palette_picker'; import { PaletteRegistry } from '../../../../charts/public'; import { PieVisParams, LabelPositions, ValueFormats } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 920566bd2962b0..830c4791714e42 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -72,6 +72,7 @@ export interface PieComponentProps { chartsThemeService: ChartsPluginSetup['theme']; palettes: PaletteRegistry; services: DataPublicPluginStart; + syncColors: boolean; } const PieComponent = (props: PieComponentProps) => { @@ -160,7 +161,7 @@ const PieComponent = (props: PieComponentProps) => { [props.uiState] ); - const { visData, visParams, palettes, services } = props; + const { visData, visParams, palettes, services, syncColors } = props; function getSliceValue(d: Datum, metricColumn: DatatableColumn) { if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { @@ -193,9 +194,18 @@ const PieComponent = (props: PieComponentProps) => { props.uiState?.get('vis.colors', {}), visData.rows.length, palettes, - services.fieldFormats + services.fieldFormats, + syncColors ), - [bucketColumns, palettes, props.uiState, services.fieldFormats, visData.rows.length, visParams] + [ + bucketColumns, + palettes, + props.uiState, + services.fieldFormats, + visData.rows.length, + visParams, + syncColors, + ] ); const config = useMemo(() => getConfig(visParams, chartTheme), [chartTheme, visParams]); const tooltip: TooltipProps = { diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index e3236a471ac6ae..0bfcce22c3fb6e 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -31,6 +31,7 @@ export interface RenderValue { visData: Datatable; visType: string; visConfig: PieVisParams; + syncColors: boolean; } export type VisTypePieExpressionFunctionDefinition = ExpressionFunctionDefinition< @@ -67,6 +68,7 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ value: { visData: context, visConfig, + syncColors: handlers?.isSyncColorsEnabled?.() ?? false, visType: 'pie', params: { listenOnChange: true, diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 9ae95b118eb858..79d70761e8ad68 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -43,7 +43,7 @@ export const getPieVisRenderer: ( name: vislibPieName, displayName: 'Pie visualization', reuseDomNode: true, - render: async (domNode, { visConfig, visData }, handlers) => { + render: async (domNode, { visConfig, visData, syncColors }, handlers) => { const showNoResult = shouldShowNoResultsMessage(visData); const isSplitChart = Boolean(visConfig.dimensions.splitRow); @@ -67,6 +67,7 @@ export const getPieVisRenderer: ( fireEvent={handlers.event} uiState={handlers.uiState as PersistedState} services={services.data} + syncColors={syncColors} /> diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index e8cd2a422e41fe..f731cc7f9e070e 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -30,7 +30,8 @@ export const getLayers = ( overwriteColors: { [key: string]: string }, totalSeries: number, palettes: PaletteRegistry, - formatter: DataPublicPluginStart['fieldFormats'] + formatter: DataPublicPluginStart['fieldFormats'], + syncColors: boolean ): PartitionLayer[] => { const fillLabel: Partial = { textInvertible: true, @@ -91,6 +92,7 @@ export const getLayers = ( behindText: visParams.labels.show, maxDepth: columns.length, totalSeries, + syncColors, }); return outputColor || 'rgba(0,0,0,0)'; diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index c1e2d8e633bce1..fa30f5bef72fbe 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1707,7 +1707,7 @@ describe('migration visualization', () => { }, }); - it('should decorate existing docs with the kibana legacy palette', () => { + it('should decorate existing docs with the kibana legacy palette - pie', () => { const migratedTestDoc = migrate(getTestDoc('pie')); const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; @@ -1721,7 +1721,7 @@ describe('migration visualization', () => { expect(isVislibVis).toEqual(true); }); - it('should decorate existing docs with the kibana legacy palette', () => { + it('should decorate existing docs with the kibana legacy palette - xy', () => { const migratedTestDoc = migrate(getTestDoc()); const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; From 0ecc168cec4112ba631a5a211f3bf92dd44826e9 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 13 Jan 2021 16:56:25 +0200 Subject: [PATCH 047/111] Lazy load palette service --- .../public/editor/components/index.tsx | 4 ++-- .../public/editor/components/pie.tsx | 20 ++++++++++++++----- .../vis_type_pie/public/pie_component.tsx | 18 +++++++++++++---- src/plugins/vis_type_pie/public/plugin.ts | 14 ++++++------- .../vis_type_pie/public/utils/get_layers.ts | 4 ++-- .../vis_type_pie/public/vis_type/index.ts | 4 ++-- .../vis_type_pie/public/vis_type/pie.tsx | 4 ++-- 7 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index d806ff7a5444d2..2c680497e03ad1 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -19,13 +19,13 @@ import { UiCounterMetricType } from '@kbn/analytics'; import React, { lazy } from 'react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; -import { PaletteRegistry } from 'src/plugins/charts/public'; +import { ChartsPluginSetup } from 'src/plugins/charts/public'; import { PieVisParams } from '../../types'; const PieOptionsLazy = lazy(() => import('./pie')); export const getPieOptions = ( - palettes: PaletteRegistry | undefined, + palettes: ChartsPluginSetup['palettes'] | undefined, showElasticChartsOptions: boolean, trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void ) => (props: VisOptionsProps) => ( diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index c5009df6f95eb8..f817c2730a7062 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { UiCounterMetricType, METRIC_TYPE } from '@kbn/analytics'; import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -30,12 +30,12 @@ import { PalettePicker, } from '../../../../vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; -import { PaletteRegistry } from '../../../../charts/public'; +import { PaletteRegistry, ChartsPluginSetup } from '../../../../charts/public'; import { PieVisParams, LabelPositions, ValueFormats } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; export interface PieOptionsProps extends VisOptionsProps { - palettes: PaletteRegistry | undefined; + palettes: ChartsPluginSetup['palettes'] | undefined; showElasticChartsOptions: boolean; trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; } @@ -47,6 +47,16 @@ const PieOptions = (props: PieOptionsProps) => { value: PieVisParams['labels'][T] ) => setValue('labels', { ...stateParams.labels, [paramName]: value }); + const [palettesRegistry, setPalettesRegistry] = useState(undefined); + + useEffect(() => { + const fetchPalettes = async () => { + const palettes = await props?.palettes?.getPalettes(); + setPalettesRegistry(palettes); + }; + fetchPalettes(); + }, [props.palettes]); + return ( <> @@ -84,9 +94,9 @@ const PieOptions = (props: PieOptionsProps) => { data-test-subj="visTypePieNestedLegendSwitch" /> )} - {props.showElasticChartsOptions && props.palettes && ( + {props.showElasticChartsOptions && palettesRegistry && ( { diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 830c4791714e42..9010e0a1dea22d 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -24,6 +24,7 @@ import React, { useCallback, useMemo, useState, + useEffect, } from 'react'; import { @@ -70,7 +71,7 @@ export interface PieComponentProps { fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; chartsThemeService: ChartsPluginSetup['theme']; - palettes: PaletteRegistry; + palettes: ChartsPluginSetup['palettes']; services: DataPublicPluginStart; syncColors: boolean; } @@ -79,6 +80,7 @@ const PieComponent = (props: PieComponentProps) => { const chartTheme = props.chartsThemeService.useChartsTheme(); const chartBaseTheme = props.chartsThemeService.useChartsBaseTheme(); const [showLegend, setShowLegend] = useState(true); + const [palettesRegistry, setPalettesRegistry] = useState(null); const onRenderChange = useCallback( (isRendered) => { @@ -89,6 +91,14 @@ const PieComponent = (props: PieComponentProps) => { [props] ); + useEffect(() => { + const fetchPalettes = async () => { + const palettes = await props.palettes.getPalettes(); + setPalettesRegistry(palettes); + }; + fetchPalettes(); + }, [props.palettes]); + // handles slice click event const handleSliceClick = useCallback( ( @@ -161,7 +171,7 @@ const PieComponent = (props: PieComponentProps) => { [props.uiState] ); - const { visData, visParams, palettes, services, syncColors } = props; + const { visData, visParams, services, syncColors } = props; function getSliceValue(d: Datum, metricColumn: DatatableColumn) { if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { @@ -193,13 +203,13 @@ const PieComponent = (props: PieComponentProps) => { visParams, props.uiState?.get('vis.colors', {}), visData.rows.length, - palettes, + palettesRegistry, services.fieldFormats, syncColors ), [ bucketColumns, - palettes, + palettesRegistry, props.uiState, services.fieldFormats, visData.rows.length, diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 5c52f803949051..b45a3b87497cee 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -19,7 +19,7 @@ import { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; -import { ChartsPluginSetup, PaletteRegistry } from '../../charts/public'; +import { ChartsPluginSetup } from '../../charts/public'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; import { LEGACY_CHARTS_LIBRARY } from '../common'; @@ -43,7 +43,7 @@ export interface VisTypePiePluginStartDependencies { /** @internal */ export interface VisTypePieDependencies { theme: ChartsPluginSetup['theme']; - palettes: PaletteRegistry; + palettes: ChartsPluginSetup['palettes']; getStartDeps: () => Promise<{ data: DataPublicPluginStart; docLinks: DocLinksStart }>; } @@ -63,12 +63,10 @@ export class VisTypePiePlugin { const trackUiMetric = usageCollection?.reportUiCounter.bind(usageCollection, 'vis_type_pie'); [createPieVisFn].forEach(expressions.registerFunction); - charts.palettes.getPalettes().then((palettes) => { - expressions.registerRenderer( - getPieVisRenderer({ theme: charts.theme, palettes, getStartDeps }) - ); - visualizations.createBaseVisualization(pieVisType(true, palettes, trackUiMetric)); - }); + expressions.registerRenderer( + getPieVisRenderer({ theme: charts.theme, palettes: charts.palettes, getStartDeps }) + ); + visualizations.createBaseVisualization(pieVisType(true, charts.palettes, trackUiMetric)); } return {}; } diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index f731cc7f9e070e..f2e768dc52e0fb 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -29,7 +29,7 @@ export const getLayers = ( visParams: PieVisParams, overwriteColors: { [key: string]: string }, totalSeries: number, - palettes: PaletteRegistry, + palettes: PaletteRegistry | null, formatter: DataPublicPluginStart['fieldFormats'], syncColors: boolean ): PartitionLayer[] => { @@ -88,7 +88,7 @@ export const getLayers = ( return lightenColor(overwriteColor, seriesLayers.length, columns.length); } - const outputColor = palettes.get(visParams.palette.name).getColor(seriesLayers, { + const outputColor = palettes?.get(visParams.palette.name).getColor(seriesLayers, { behindText: visParams.labels.show, maxDepth: columns.length, totalSeries, diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index 9b1d41fa5b4442..d956ad66f79fe0 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -17,12 +17,12 @@ * under the License. */ import { UiCounterMetricType } from '@kbn/analytics'; -import { PaletteRegistry } from '../../../charts/public'; +import { ChartsPluginSetup } from '../../../charts/public'; import { getPieVisTypeDefinition } from './pie'; export const pieVisType = ( showElasticChartsOptions?: boolean, - palettes?: PaletteRegistry, + palettes?: ChartsPluginSetup['palettes'], trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void ) => { return getPieVisTypeDefinition(showElasticChartsOptions, palettes, trackUiMetric); diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index f8bbd81828513d..4c77dc4e50ba31 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; import { UiCounterMetricType } from '@kbn/analytics'; import { AggGroupNames } from '../../../data/public'; -import { PaletteRegistry } from '../../../charts/public'; +import { ChartsPluginSetup } from '../../../charts/public'; import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualizations/public'; import { PieVisParams, LabelPositions, ValueFormats } from '../types'; @@ -32,7 +32,7 @@ import { SplitTooltip } from './split_tooltip'; export const getPieVisTypeDefinition = ( showElasticChartsOptions = false, - palettes: PaletteRegistry | undefined, + palettes: ChartsPluginSetup['palettes'] | undefined, trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void ): BaseVisTypeOptions => ({ name: 'pie', From cd2f7bb0695d55155840462d9fd9abb90c1aeba4 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 14 Jan 2021 13:06:09 +0200 Subject: [PATCH 048/111] Add the new plugin to ts references, fix tests, refactor --- .../public/__snapshots__/pie_fn.test.ts.snap | 1 + .../public/editor/components/index.tsx | 14 ++--- .../public/editor/components/pie.test.tsx | 61 +++++++++++-------- .../public/editor/components/pie.tsx | 14 ++--- .../public/pie_component.test.tsx | 16 +++-- src/plugins/vis_type_pie/public/plugin.ts | 8 ++- .../vis_type_pie/public/types/types.ts | 9 ++- .../vis_type_pie/public/vis_type/index.ts | 12 ++-- .../vis_type_pie/public/vis_type/pie.tsx | 19 +++--- src/plugins/vis_type_pie/tsconfig.json | 24 ++++++++ src/plugins/vis_type_vislib/public/pie.ts | 2 +- src/plugins/vis_type_vislib/tsconfig.json | 1 + tsconfig.json | 2 + 13 files changed, 114 insertions(+), 69 deletions(-) create mode 100644 src/plugins/vis_type_pie/tsconfig.json diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 66b34b6c211190..31133d816ee90b 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -8,6 +8,7 @@ Object { "params": Object { "listenOnChange": true, }, + "syncColors": false, "visConfig": Object { "addLegend": true, "addTooltip": true, diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index 2c680497e03ad1..45494c7f8a9434 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -16,19 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -import { UiCounterMetricType } from '@kbn/analytics'; import React, { lazy } from 'react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; -import { ChartsPluginSetup } from 'src/plugins/charts/public'; -import { PieVisParams } from '../../types'; +import { PieVisParams, PieTypeProps } from '../../types'; const PieOptionsLazy = lazy(() => import('./pie')); -export const getPieOptions = ( - palettes: ChartsPluginSetup['palettes'] | undefined, - showElasticChartsOptions: boolean, - trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void -) => (props: VisOptionsProps) => ( +export const getPieOptions = ({ + showElasticChartsOptions, + palettes, + trackUiMetric, +}: PieTypeProps) => (props: VisOptionsProps) => ( ({ getLabelPositions: jest.fn(() => []), @@ -34,7 +35,7 @@ describe('PalettePicker', function () { beforeAll(() => { props = ({ - palettes: chartPluginMock.createPaletteRegistry(), + palettes: chartPluginMock.createSetupContract().palettes, showElasticChartsOptions: true, vis: { type: { @@ -72,53 +73,59 @@ describe('PalettePicker', function () { } as unknown) as PieOptionsProps; }); - it('renders the nested legend switch for the elastic charts implementation', () => { + it('renders the nested legend switch for the elastic charts implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(1); + await act(async () => { + expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(1); + }); }); - it('not renders the nested legend switch for the vislib implementation', () => { + it('not renders the nested legend switch for the vislib implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(0); + await act(async () => { + expect(findTestSubject(component, 'visTypePieNestedLegendSwitch').length).toBe(0); + }); }); - it('renders the palettes picker for the elastic charts implementation', () => { + it('renders the label position dropdown for the elastic charts implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'piePalettePicker').length).toBe(1); + await act(async () => { + expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(1); + }); }); - it('not renders the palettes picker for the vislib implementation', () => { + it('not renders the label position dropdown for the vislib implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'piePalettePicker').length).toBe(0); + await act(async () => { + expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(0); + }); }); - it('renders the label position dropdown for the elastic charts implementation', () => { + it('not renders the top level switch for the elastic charts implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(1); + await act(async () => { + expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(0); + }); }); - it('not renders the label position dropdown for the vislib implementation', () => { + it('renders the top level switch for the vislib implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieLabelPositionSelect').length).toBe(0); + await act(async () => { + expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(1); + }); }); - it('not renders the top level switch for the elastic charts implementation', () => { + it('renders the value format dropdown for the elastic charts implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(0); + await act(async () => { + expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(1); + }); }); - it('renders the top level switch for the vislib implementation', () => { + it('not renders the value format dropdown for the vislib implementation', async () => { component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(1); - }); - - it('renders the value format dropdown for the elastic charts implementation', () => { - component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(1); - }); - - it('not renders the value format dropdown for the vislib implementation', () => { - component = mountWithIntl(); - expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(0); + await act(async () => { + expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(0); + }); }); }); diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index f817c2730a7062..456575c4819f9c 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -17,7 +17,7 @@ * under the License. */ import React, { useState, useEffect } from 'react'; -import { UiCounterMetricType, METRIC_TYPE } from '@kbn/analytics'; +import { METRIC_TYPE } from '@kbn/analytics'; import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -30,15 +30,11 @@ import { PalettePicker, } from '../../../../vis_default_editor/public'; import { TruncateLabelsOption } from './truncate_labels'; -import { PaletteRegistry, ChartsPluginSetup } from '../../../../charts/public'; -import { PieVisParams, LabelPositions, ValueFormats } from '../../types'; +import { PaletteRegistry } from '../../../../charts/public'; +import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; -export interface PieOptionsProps extends VisOptionsProps { - palettes: ChartsPluginSetup['palettes'] | undefined; - showElasticChartsOptions: boolean; - trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; -} +export interface PieOptionsProps extends VisOptionsProps, PieTypeProps {} const PieOptions = (props: PieOptionsProps) => { const { stateParams, setValue } = props; @@ -51,7 +47,7 @@ const PieOptions = (props: PieOptionsProps) => { useEffect(() => { const fetchPalettes = async () => { - const palettes = await props?.palettes?.getPalettes(); + const palettes = await props.palettes?.getPalettes(); setPalettesRegistry(palettes); }; fetchPalettes(); diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index 56d94e6a95f2c1..febf803ee4385c 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -22,6 +22,7 @@ import { chartPluginMock } from '../../charts/public/mocks'; import { dataPluginMock } from '../../data/public/mocks'; import { shallow, mount } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; +import { act } from 'react-dom/test-utils'; import PieComponent, { PieComponentProps } from './pie_component'; import { createMockPieParams, createMockVisData } from './mocks'; @@ -35,7 +36,7 @@ jest.mock('@elastic/charts', () => { }); const chartsThemeService = chartPluginMock.createSetupContract().theme; -const palettes = chartPluginMock.createPaletteRegistry(); +const palettes = chartPluginMock.createSetupContract().palettes; const visParams = createMockPieParams(); const visData = createMockVisData(); @@ -59,6 +60,7 @@ describe('PieComponent', function () { visParams, visData, uiState, + syncColors: false, fireEvent: jest.fn(), renderComplete: jest.fn(), services: dataPluginMock.createStartContract(), @@ -70,15 +72,19 @@ describe('PieComponent', function () { expect(component.find(Settings).prop('legendPosition')).toEqual('right'); }); - it('renders the legend toggle component', () => { + it('renders the legend toggle component', async () => { const component = mount(); - expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1); + await act(async () => { + expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1); + }); }); - it('hides the legend if the legend toggle is clicked', () => { + it('hides the legend if the legend toggle is clicked', async () => { const component = mount(); findTestSubject(component, 'vislibToggleLegend').simulate('click'); - expect(component.find(Settings).prop('showLegend')).toEqual(false); + await act(async () => { + expect(component.find(Settings).prop('showLegend')).toEqual(false); + }); }); it('defaults on showing the legend for the inner cicle', () => { diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index b45a3b87497cee..f25396e47da0c6 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -66,7 +66,13 @@ export class VisTypePiePlugin { expressions.registerRenderer( getPieVisRenderer({ theme: charts.theme, palettes: charts.palettes, getStartDeps }) ); - visualizations.createBaseVisualization(pieVisType(true, charts.palettes, trackUiMetric)); + visualizations.createBaseVisualization( + pieVisType({ + showElasticChartsOptions: true, + palettes: charts.palettes, + trackUiMetric, + }) + ); } return {}; } diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 30940ccc3c9a6b..2740c270c36cf0 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -17,8 +17,9 @@ * under the License. */ import { Position } from '@elastic/charts'; +import { UiCounterMetricType } from '@kbn/analytics'; import { DatatableColumn, SerializedFieldFormat } from '../../../expressions/public'; -import { PaletteOutput } from '../../../charts/public'; +import { PaletteOutput, ChartsPluginSetup } from '../../../charts/public'; export interface Dimension { accessor: number; @@ -70,3 +71,9 @@ export enum ValueFormats { PERCENT = 'percent', VALUE = 'value', } + +export interface PieTypeProps { + showElasticChartsOptions?: boolean; + palettes?: ChartsPluginSetup['palettes']; + trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; +} diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index d956ad66f79fe0..75a1f35dd72149 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -16,14 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { UiCounterMetricType } from '@kbn/analytics'; -import { ChartsPluginSetup } from '../../../charts/public'; + import { getPieVisTypeDefinition } from './pie'; +import type { PieTypeProps } from '../types'; -export const pieVisType = ( - showElasticChartsOptions?: boolean, - palettes?: ChartsPluginSetup['palettes'], - trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void -) => { - return getPieVisTypeDefinition(showElasticChartsOptions, palettes, trackUiMetric); +export const pieVisType = (props: PieTypeProps) => { + return getPieVisTypeDefinition(props); }; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index 4c77dc4e50ba31..1ccd6367215699 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -19,22 +19,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; -import { UiCounterMetricType } from '@kbn/analytics'; import { AggGroupNames } from '../../../data/public'; -import { ChartsPluginSetup } from '../../../charts/public'; import { VIS_EVENT_TO_TRIGGER, BaseVisTypeOptions } from '../../../visualizations/public'; - -import { PieVisParams, LabelPositions, ValueFormats } from '../types'; +import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../types'; import { toExpressionAst } from '../to_ast'; import { getLegendPositions } from '../editor'; import { getPieOptions } from '../editor/components'; import { SplitTooltip } from './split_tooltip'; -export const getPieVisTypeDefinition = ( +export const getPieVisTypeDefinition = ({ showElasticChartsOptions = false, - palettes: ChartsPluginSetup['palettes'] | undefined, - trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void -): BaseVisTypeOptions => ({ + palettes, + trackUiMetric, +}: PieTypeProps): BaseVisTypeOptions => ({ name: 'pie', title: i18n.translate('visTypePie.pie.pieTitle', { defaultMessage: 'Pie' }), icon: 'visPie', @@ -69,7 +66,11 @@ export const getPieVisTypeDefinition = ( collections: { legendPositions: getLegendPositions(), }, - optionsTemplate: getPieOptions(palettes, showElasticChartsOptions, trackUiMetric), + optionsTemplate: getPieOptions({ + showElasticChartsOptions, + palettes, + trackUiMetric, + }), schemas: [ { group: AggGroupNames.Metrics, diff --git a/src/plugins/vis_type_pie/tsconfig.json b/src/plugins/vis_type_pie/tsconfig.json new file mode 100644 index 00000000000000..f12db316f19723 --- /dev/null +++ b/src/plugins/vis_type_pie/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*" + ], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../charts/tsconfig.json" }, + { "path": "../data/tsconfig.json" }, + { "path": "../expressions/tsconfig.json" }, + { "path": "../visualizations/tsconfig.json" }, + { "path": "../usage_collection/tsconfig.json" }, + { "path": "../vis_default_editor/tsconfig.json" }, + ] + } \ No newline at end of file diff --git a/src/plugins/vis_type_vislib/public/pie.ts b/src/plugins/vis_type_vislib/public/pie.ts index 94ac0444e77c13..74aaf72e42a9f1 100644 --- a/src/plugins/vis_type_vislib/public/pie.ts +++ b/src/plugins/vis_type_vislib/public/pie.ts @@ -34,7 +34,7 @@ export interface PieVisParams extends CommonVislibParams { } export const pieVisTypeDefinition: BaseVisTypeOptions = { - ...(pieVisType() as BaseVisTypeOptions), + ...(pieVisType({}) as BaseVisTypeOptions), toExpressionAst, visualization: undefined, }; diff --git a/src/plugins/vis_type_vislib/tsconfig.json b/src/plugins/vis_type_vislib/tsconfig.json index 74bc1440d9dbc6..5bf1af9ba75fea 100644 --- a/src/plugins/vis_type_vislib/tsconfig.json +++ b/src/plugins/vis_type_vislib/tsconfig.json @@ -22,5 +22,6 @@ { "path": "../kibana_utils/tsconfig.json" }, { "path": "../vis_default_editor/tsconfig.json" }, { "path": "../vis_type_xy/tsconfig.json" }, + { "path": "../vis_type_pie/tsconfig.json" }, ] } diff --git a/tsconfig.json b/tsconfig.json index b6742bffeab55c..d86087055525a1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -52,6 +52,7 @@ "src/plugins/vis_type_timeseries/**/*", "src/plugins/vis_type_vislib/**/*", "src/plugins/vis_type_xy/**/*", + "src/plugins/vis_type_pie/**/*", "src/plugins/visualizations/**/*", "src/plugins/visualize/**/*", // In the build we actually exclude **/public/**/* from this config so that @@ -106,6 +107,7 @@ { "path": "./src/plugins/vis_type_timeseries/tsconfig.json" }, { "path": "./src/plugins/vis_type_vislib/tsconfig.json" }, { "path": "./src/plugins/vis_type_xy/tsconfig.json" }, + { "path": "./src/plugins/vis_type_pie/tsconfig.json" }, { "path": "./src/plugins/visualizations/tsconfig.json" }, { "path": "./src/plugins/visualize/tsconfig.json" }, ] From 0fbdd09578fbba6dfd1a1bf33b12eed8c425487a Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 14 Jan 2021 13:29:13 +0200 Subject: [PATCH 049/111] Fix ci failure --- .../public/sample_vis.test.mocks.ts | 1340 +++++++++++++++++ .../vis_type_pie/public/to_ast.test.ts | 2 +- .../vis_type_vislib/public/to_ast_pie.test.ts | 2 +- .../public/sample_vis.test.mocks.ts | 1323 ---------------- 4 files changed, 1342 insertions(+), 1325 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts diff --git a/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts new file mode 100644 index 00000000000000..e9fa8a44209022 --- /dev/null +++ b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts @@ -0,0 +1,1340 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const samplePieVis = { + type: { + name: 'pie', + title: 'Pie', + description: 'Compare parts of a whole', + icon: 'visPie', + stage: 'production', + options: { + showTimePicker: true, + showQueryBar: true, + showFilterBar: true, + showIndexSelection: true, + hierarchicalData: false, + }, + visConfig: { + defaults: { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: 'right', + isDonut: true, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, + }, + }, + editorConfig: { + collections: { + legendPositions: [ + { + text: 'Top', + value: 'top', + }, + { + text: 'Left', + value: 'left', + }, + { + text: 'Right', + value: 'right', + }, + { + text: 'Bottom', + value: 'bottom', + }, + ], + }, + schemas: { + all: [ + { + group: 'metrics', + name: 'metric', + title: 'Slice size', + min: 1, + max: 1, + aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], + defaults: [ + { + schema: 'metric', + type: 'count', + }, + ], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'segment', + title: 'Split slices', + min: 0, + max: null, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'split', + title: 'Split chart', + mustBeFirst: true, + min: 0, + max: 1, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + params: [ + { + name: 'row', + default: true, + }, + ], + editor: false, + }, + ], + buckets: [null, null], + metrics: [null], + }, + }, + hidden: false, + requestHandler: 'courier', + responseHandler: 'vislib_slices', + hierarchicalData: true, + useCustomNoDataScreen: false, + }, + title: '[Flights] Airline Carrier', + description: '', + params: { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: 'right', + isDonut: true, + labels: { + show: true, + values: true, + last_level: true, + truncate: 100, + }, + }, + sessionState: {}, + data: { + searchSource: { + id: 'data_source1', + requestStartHandlers: [], + inheritOptions: {}, + history: [], + fields: { + filter: [], + query: { + query: '', + language: 'kuery', + }, + index: { + id: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + title: 'kibana_sample_data_flights', + fieldFormatMap: { + AvgTicketPrice: { + id: 'number', + params: { + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + pattern: '$0,0.[00]', + }, + }, + hour_of_day: { + id: 'number', + params: { + pattern: '00', + }, + }, + }, + fields: [ + { + count: 0, + name: 'AvgTicketPrice', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Cancelled', + type: 'boolean', + esTypes: ['boolean'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Carrier', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Dest', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestAirportID', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestCityName', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestCountry', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestLocation', + type: 'geo_point', + esTypes: ['geo_point'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestRegion', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestWeather', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DistanceKilometers', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DistanceMiles', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelay', + type: 'boolean', + esTypes: ['boolean'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelayMin', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelayType', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightNum', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightTimeHour', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightTimeMin', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Origin', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginAirportID', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginCityName', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginCountry', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginLocation', + type: 'geo_point', + esTypes: ['geo_point'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginRegion', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginWeather', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: '_id', + type: 'string', + esTypes: ['_id'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_index', + type: 'string', + esTypes: ['_index'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_score', + type: 'number', + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_source', + type: '_source', + esTypes: ['_source'], + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_type', + type: 'string', + esTypes: ['_type'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: 'dayOfWeek', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'timestamp', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + script: "doc['timestamp'].value.hourOfDay", + lang: 'painless', + name: 'hour_of_day', + type: 'number', + scripted: true, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + ], + timeFieldName: 'timestamp', + metaFields: ['_source', '_id', '_type', '_index', '_score'], + version: 'WzM1LDFd', + originalSavedObjectBody: { + title: 'kibana_sample_data_flights', + timeFieldName: 'timestamp', + fields: + '[{"count":0,"name":"AvgTicketPrice","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Cancelled","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Carrier","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Dest","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceKilometers","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceMiles","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelay","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayMin","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayType","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightNum","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeHour","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeMin","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Origin","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"_id","type":"string","esTypes":["_id"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_index","type":"string","esTypes":["_index"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_score","type":"number","scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_source","type":"_source","esTypes":["_source"],"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_type","type":"string","esTypes":["_type"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"dayOfWeek","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"timestamp","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"script":"doc[\'timestamp\'].value.hourOfDay","lang":"painless","name":"hour_of_day","type":"number","scripted":true,"searchable":true,"aggregatable":true,"readFromDocValues":false}]', + fieldFormatMap: + '{"AvgTicketPrice":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"$0,0.[00]"}},"hour_of_day":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"00"}}}', + }, + shortDotsEnable: false, + fieldFormats: { + fieldFormats: {}, + defaultMap: { + ip: { + id: 'ip', + params: {}, + }, + date: { + id: 'date', + params: {}, + }, + date_nanos: { + id: 'date_nanos', + params: {}, + es: true, + }, + number: { + id: 'number', + params: {}, + }, + boolean: { + id: 'boolean', + params: {}, + }, + _source: { + id: '_source', + params: {}, + }, + _default_: { + id: 'string', + params: {}, + }, + }, + metaParamsOptions: {}, + }, + }, + }, + dependencies: { + legacy: { + loadingCount$: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + destination: { + closed: true, + }, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 13, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 3, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + }, + }, + aggs: { + typesRegistry: {}, + getResponseAggs: () => [ + { + id: '1', + enabled: true, + type: 'count', + params: {}, + schema: 'metric', + toSerializedFieldFormat: () => ({ + id: 'number', + }), + }, + { + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + toSerializedFieldFormat: () => ({ + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + }, + }), + }, + ], + }, + }, + isHierarchical: () => true, + uiState: { + vis: { + legendOpen: false, + }, + }, +}; diff --git a/src/plugins/vis_type_pie/public/to_ast.test.ts b/src/plugins/vis_type_pie/public/to_ast.test.ts index 614475a2ca622c..29065190980c0e 100644 --- a/src/plugins/vis_type_pie/public/to_ast.test.ts +++ b/src/plugins/vis_type_pie/public/to_ast.test.ts @@ -21,7 +21,7 @@ import { Vis } from '../../visualizations/public'; import { buildExpression } from '../../expressions/public'; import { PieVisParams } from './types'; -import { samplePieVis } from '../../vis_type_vislib/public/sample_vis.test.mocks'; +import { samplePieVis } from './sample_vis.test.mocks'; import { toExpressionAst } from './to_ast'; jest.mock('../../expressions/public', () => ({ diff --git a/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts b/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts index 08a74a37f380ce..0dca2e12d8842b 100644 --- a/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts +++ b/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts @@ -21,7 +21,7 @@ import { Vis } from '../../visualizations/public'; import { buildExpression } from '../../expressions/public'; import { PieVisParams } from './pie'; -import { samplePieVis } from '../../vis_type_xy/public/sample_vis.test.mocks'; +import { samplePieVis } from '../../vis_type_pie/public/sample_vis.test.mocks'; import { toExpressionAst } from './to_ast_pie'; jest.mock('../../expressions/public', () => ({ diff --git a/src/plugins/vis_type_xy/public/sample_vis.test.mocks.ts b/src/plugins/vis_type_xy/public/sample_vis.test.mocks.ts index 324e8e00f37fc1..9d6a79b92ec52f 100644 --- a/src/plugins/vis_type_xy/public/sample_vis.test.mocks.ts +++ b/src/plugins/vis_type_xy/public/sample_vis.test.mocks.ts @@ -16,1329 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - -export const samplePieVis = { - type: { - name: 'pie', - title: 'Pie', - description: 'Compare parts of a whole', - icon: 'visPie', - stage: 'production', - options: { - showTimePicker: true, - showQueryBar: true, - showFilterBar: true, - showIndexSelection: true, - hierarchicalData: false, - }, - visConfig: { - defaults: { - type: 'pie', - addTooltip: true, - addLegend: true, - legendPosition: 'right', - isDonut: true, - labels: { - show: false, - values: true, - last_level: true, - truncate: 100, - }, - }, - }, - editorConfig: { - collections: { - legendPositions: [ - { - text: 'Top', - value: 'top', - }, - { - text: 'Left', - value: 'left', - }, - { - text: 'Right', - value: 'right', - }, - { - text: 'Bottom', - value: 'bottom', - }, - ], - }, - schemas: { - all: [ - { - group: 'metrics', - name: 'metric', - title: 'Slice size', - min: 1, - max: 1, - aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], - defaults: [ - { - schema: 'metric', - type: 'count', - }, - ], - editor: false, - params: [], - }, - { - group: 'buckets', - name: 'segment', - title: 'Split slices', - min: 0, - max: null, - aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], - editor: false, - params: [], - }, - { - group: 'buckets', - name: 'split', - title: 'Split chart', - mustBeFirst: true, - min: 0, - max: 1, - aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], - params: [ - { - name: 'row', - default: true, - }, - ], - editor: false, - }, - ], - buckets: [null, null], - metrics: [null], - }, - }, - hidden: false, - requestHandler: 'courier', - responseHandler: 'vislib_slices', - hierarchicalData: true, - useCustomNoDataScreen: false, - }, - title: '[Flights] Airline Carrier', - description: '', - params: { - type: 'pie', - addTooltip: true, - addLegend: true, - legendPosition: 'right', - isDonut: true, - labels: { - show: true, - values: true, - last_level: true, - truncate: 100, - }, - }, - sessionState: {}, - data: { - searchSource: { - id: 'data_source1', - requestStartHandlers: [], - inheritOptions: {}, - history: [], - fields: { - filter: [], - query: { - query: '', - language: 'kuery', - }, - index: { - id: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - title: 'kibana_sample_data_flights', - fieldFormatMap: { - AvgTicketPrice: { - id: 'number', - params: { - parsedUrl: { - origin: 'http://localhost:5801', - pathname: '/app/visualize', - basePath: '', - }, - pattern: '$0,0.[00]', - }, - }, - hour_of_day: { - id: 'number', - params: { - pattern: '00', - }, - }, - }, - fields: [ - { - count: 0, - name: 'AvgTicketPrice', - type: 'number', - esTypes: ['float'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'Cancelled', - type: 'boolean', - esTypes: ['boolean'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'Carrier', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'Dest', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestAirportID', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestCityName', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestCountry', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestLocation', - type: 'geo_point', - esTypes: ['geo_point'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestRegion', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DestWeather', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DistanceKilometers', - type: 'number', - esTypes: ['float'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'DistanceMiles', - type: 'number', - esTypes: ['float'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightDelay', - type: 'boolean', - esTypes: ['boolean'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightDelayMin', - type: 'number', - esTypes: ['integer'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightDelayType', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightNum', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightTimeHour', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'FlightTimeMin', - type: 'number', - esTypes: ['float'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'Origin', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginAirportID', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginCityName', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginCountry', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginLocation', - type: 'geo_point', - esTypes: ['geo_point'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginRegion', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'OriginWeather', - type: 'string', - esTypes: ['keyword'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: '_id', - type: 'string', - esTypes: ['_id'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - { - count: 0, - name: '_index', - type: 'string', - esTypes: ['_index'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - { - count: 0, - name: '_score', - type: 'number', - scripted: false, - searchable: false, - aggregatable: false, - readFromDocValues: false, - }, - { - count: 0, - name: '_source', - type: '_source', - esTypes: ['_source'], - scripted: false, - searchable: false, - aggregatable: false, - readFromDocValues: false, - }, - { - count: 0, - name: '_type', - type: 'string', - esTypes: ['_type'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - { - count: 0, - name: 'dayOfWeek', - type: 'number', - esTypes: ['integer'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - name: 'timestamp', - type: 'date', - esTypes: ['date'], - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - { - count: 0, - script: "doc['timestamp'].value.hourOfDay", - lang: 'painless', - name: 'hour_of_day', - type: 'number', - scripted: true, - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - ], - timeFieldName: 'timestamp', - metaFields: ['_source', '_id', '_type', '_index', '_score'], - version: 'WzM1LDFd', - originalSavedObjectBody: { - title: 'kibana_sample_data_flights', - timeFieldName: 'timestamp', - fields: - '[{"count":0,"name":"AvgTicketPrice","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Cancelled","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Carrier","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Dest","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceKilometers","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceMiles","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelay","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayMin","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayType","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightNum","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeHour","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeMin","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Origin","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"_id","type":"string","esTypes":["_id"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_index","type":"string","esTypes":["_index"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_score","type":"number","scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_source","type":"_source","esTypes":["_source"],"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_type","type":"string","esTypes":["_type"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"dayOfWeek","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"timestamp","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"script":"doc[\'timestamp\'].value.hourOfDay","lang":"painless","name":"hour_of_day","type":"number","scripted":true,"searchable":true,"aggregatable":true,"readFromDocValues":false}]', - fieldFormatMap: - '{"AvgTicketPrice":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"$0,0.[00]"}},"hour_of_day":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"00"}}}', - }, - shortDotsEnable: false, - fieldFormats: { - fieldFormats: {}, - defaultMap: { - ip: { - id: 'ip', - params: {}, - }, - date: { - id: 'date', - params: {}, - }, - date_nanos: { - id: 'date_nanos', - params: {}, - es: true, - }, - number: { - id: 'number', - params: {}, - }, - boolean: { - id: 'boolean', - params: {}, - }, - _source: { - id: '_source', - params: {}, - }, - _default_: { - id: 'string', - params: {}, - }, - }, - metaParamsOptions: {}, - }, - }, - }, - dependencies: { - legacy: { - loadingCount$: { - _isScalar: false, - observers: [ - { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: null, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - destination: { - closed: false, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - destination: { - closed: true, - }, - _context: {}, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - count: 1, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - hasPrev: true, - prev: 0, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [], - active: 1, - index: 2, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [ - { - _isScalar: false, - }, - ], - active: 1, - index: 1, - }, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - subject: { - _isScalar: false, - observers: [ - { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: null, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - destination: { - closed: false, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - _context: {}, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - count: 13, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - hasPrev: true, - prev: 0, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [], - active: 1, - index: 2, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [ - { - _isScalar: false, - }, - ], - active: 1, - index: 1, - }, - }, - _subscriptions: [ - null, - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - subject: { - _isScalar: false, - observers: [null], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - _value: 0, - }, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - hasKey: true, - key: 0, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - seenValue: false, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: null, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - destination: { - closed: false, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - _context: {}, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - count: 1, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - hasPrev: true, - prev: 0, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [], - active: 1, - index: 2, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [ - { - _isScalar: false, - }, - ], - active: 1, - index: 1, - }, - }, - _subscriptions: [ - null, - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - subject: { - _isScalar: false, - observers: [null], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - _value: 0, - }, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - hasKey: true, - key: 0, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - seenValue: false, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: null, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - destination: { - closed: false, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - _context: {}, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - count: 1, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - hasPrev: true, - prev: 0, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [], - active: 1, - index: 2, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [ - { - _isScalar: false, - }, - ], - active: 1, - index: 1, - }, - }, - _subscriptions: [ - null, - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - subject: { - _isScalar: false, - observers: [null], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - _value: 0, - }, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - hasKey: true, - key: 0, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - seenValue: false, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: { - closed: false, - _parentOrParents: null, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - destination: { - closed: false, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - _context: {}, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - count: 3, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: false, - hasPrev: true, - prev: 0, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: true, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [], - active: 1, - index: 2, - }, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - parent: { - closed: true, - _parentOrParents: null, - _subscriptions: null, - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: true, - concurrent: 1, - hasCompleted: true, - buffer: [ - { - _isScalar: false, - }, - ], - active: 1, - index: 1, - }, - }, - _subscriptions: [ - null, - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - subject: { - _isScalar: false, - observers: [null], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - _value: 0, - }, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - hasKey: true, - key: 0, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - seenValue: false, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - null, - ], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - }, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - null, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - seenValue: false, - }, - _subscriptions: [null], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - }, - _subscriptions: [ - { - closed: false, - _subscriptions: null, - }, - ], - syncErrorValue: null, - syncErrorThrown: false, - syncErrorThrowable: false, - isStopped: false, - hasKey: true, - key: 0, - }, - ], - closed: false, - isStopped: false, - hasError: false, - thrownError: null, - _value: 0, - }, - }, - }, - }, - aggs: { - typesRegistry: {}, - getResponseAggs: () => [ - { - id: '1', - enabled: true, - type: 'count', - params: {}, - schema: 'metric', - toSerializedFieldFormat: () => ({ - id: 'number', - }), - }, - { - id: '2', - enabled: true, - type: 'terms', - params: { - field: 'Carrier', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'segment', - toSerializedFieldFormat: () => ({ - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - parsedUrl: { - origin: 'http://localhost:5801', - pathname: '/app/visualize', - basePath: '', - }, - }, - }), - }, - ], - }, - }, - isHierarchical: () => true, - uiState: { - vis: { - legendOpen: false, - }, - }, -}; - export const sampleAreaVis = { type: { name: 'area', From 663f641c5b75d89fc96fbf3452611c515e077a8c Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 14 Jan 2021 14:57:03 +0200 Subject: [PATCH 050/111] Move charts library switch to vislib plugin --- src/plugins/vis_type_pie/common/index.ts | 20 ------- src/plugins/vis_type_pie/kibana.json | 2 +- src/plugins/vis_type_pie/public/plugin.ts | 2 +- src/plugins/vis_type_pie/tsconfig.json | 1 + src/plugins/vis_type_vislib/common/index.ts | 1 + src/plugins/vis_type_vislib/kibana.json | 3 +- src/plugins/vis_type_vislib/public/plugin.ts | 2 +- .../vis_type_vislib/server/ui_settings.ts | 23 +++++++- src/plugins/vis_type_xy/common/index.ts | 2 - src/plugins/vis_type_xy/kibana.json | 3 +- src/plugins/vis_type_xy/public/plugin.ts | 2 +- src/plugins/vis_type_xy/server/index.ts | 22 ------- src/plugins/vis_type_xy/server/plugin.ts | 57 ------------------- src/plugins/vis_type_xy/tsconfig.json | 1 + 14 files changed, 32 insertions(+), 109 deletions(-) delete mode 100644 src/plugins/vis_type_pie/common/index.ts delete mode 100644 src/plugins/vis_type_xy/server/index.ts delete mode 100644 src/plugins/vis_type_xy/server/plugin.ts diff --git a/src/plugins/vis_type_pie/common/index.ts b/src/plugins/vis_type_pie/common/index.ts deleted file mode 100644 index 9b7e834d6ce0f4..00000000000000 --- a/src/plugins/vis_type_pie/common/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_pie/kibana.json b/src/plugins/vis_type_pie/kibana.json index c2d51fba8260dd..86af73ba6aef54 100644 --- a/src/plugins/vis_type_pie/kibana.json +++ b/src/plugins/vis_type_pie/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"], - "requiredBundles": ["visDefaultEditor"] + "requiredBundles": ["visDefaultEditor", "visTypeVislib"] } \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index f25396e47da0c6..dcb64bb6ffce41 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -22,7 +22,7 @@ import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup } from '../../charts/public'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; -import { LEGACY_CHARTS_LIBRARY } from '../common'; +import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_vislib/common/index'; import { createPieVisFn } from './pie_fn'; import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; diff --git a/src/plugins/vis_type_pie/tsconfig.json b/src/plugins/vis_type_pie/tsconfig.json index f12db316f19723..6a05844dfc2b9f 100644 --- a/src/plugins/vis_type_pie/tsconfig.json +++ b/src/plugins/vis_type_pie/tsconfig.json @@ -20,5 +20,6 @@ { "path": "../visualizations/tsconfig.json" }, { "path": "../usage_collection/tsconfig.json" }, { "path": "../vis_default_editor/tsconfig.json" }, + { "path": "../vis_type_vislib/tsconfig.json" }, ] } \ No newline at end of file diff --git a/src/plugins/vis_type_vislib/common/index.ts b/src/plugins/vis_type_vislib/common/index.ts index e497253761a719..37912a9a1af493 100644 --- a/src/plugins/vis_type_vislib/common/index.ts +++ b/src/plugins/vis_type_vislib/common/index.ts @@ -19,3 +19,4 @@ export const DIMMING_OPACITY_SETTING = 'visualization:dimmingOpacity'; export const HEATMAP_MAX_BUCKETS_SETTING = 'visualization:heatmap:maxBuckets'; +export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_vislib/kibana.json b/src/plugins/vis_type_vislib/kibana.json index 56dfba0aca59c0..c9f5360c8ad410 100644 --- a/src/plugins/vis_type_vislib/kibana.json +++ b/src/plugins/vis_type_vislib/kibana.json @@ -4,5 +4,6 @@ "server": true, "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "kibanaLegacy"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeXy", "visTypePie"] + "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeXy", "visTypePie"], + "extraPublicDirs": ["common/index"] } diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts index f0b8479f7beaa6..fd04918cf78914 100644 --- a/src/plugins/vis_type_vislib/public/plugin.ts +++ b/src/plugins/vis_type_vislib/public/plugin.ts @@ -24,7 +24,7 @@ import { VisualizationsSetup } from '../../visualizations/public'; import { ChartsPluginSetup } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; import { KibanaLegacyStart } from '../../kibana_legacy/public'; -import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_xy/public'; +import { LEGACY_CHARTS_LIBRARY } from '../common'; import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn'; import { createPieVisFn } from './pie_fn'; diff --git a/src/plugins/vis_type_vislib/server/ui_settings.ts b/src/plugins/vis_type_vislib/server/ui_settings.ts index 58564b4055daa8..7dcdc4f7eb490f 100644 --- a/src/plugins/vis_type_vislib/server/ui_settings.ts +++ b/src/plugins/vis_type_vislib/server/ui_settings.ts @@ -21,7 +21,11 @@ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from 'kibana/server'; -import { DIMMING_OPACITY_SETTING, HEATMAP_MAX_BUCKETS_SETTING } from '../common'; +import { + DIMMING_OPACITY_SETTING, + HEATMAP_MAX_BUCKETS_SETTING, + LEGACY_CHARTS_LIBRARY, +} from '../common'; export const uiSettings: Record = { // TODO: move this to vis_type_xy when vislib is removed @@ -58,4 +62,21 @@ export const uiSettings: Record = { category: ['visualization'], schema: schema.number(), }, + // TODO: Remove this when vis_type_vislib is removed + // https://github.com/elastic/kibana/issues/56143 + [LEGACY_CHARTS_LIBRARY]: { + name: i18n.translate('visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.name', { + defaultMessage: 'Legacy charts library', + }), + value: false, + description: i18n.translate( + 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.description', + { + defaultMessage: + 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.', + } + ), + category: ['visualization'], + schema: schema.boolean(), + }, }; diff --git a/src/plugins/vis_type_xy/common/index.ts b/src/plugins/vis_type_xy/common/index.ts index edee1ea3219db6..201657d7265500 100644 --- a/src/plugins/vis_type_xy/common/index.ts +++ b/src/plugins/vis_type_xy/common/index.ts @@ -33,5 +33,3 @@ export type ChartType = $Values; * Type of xy visualizations */ export type XyVisType = ChartType | 'horizontal_bar'; - -export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_xy/kibana.json b/src/plugins/vis_type_xy/kibana.json index 619fa8e71c0dde..f38d48a6b28b26 100644 --- a/src/plugins/vis_type_xy/kibana.json +++ b/src/plugins/vis_type_xy/kibana.json @@ -1,8 +1,7 @@ { "id": "visTypeXy", "version": "kibana", - "server": true, "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor"] + "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeVislib"] } diff --git a/src/plugins/vis_type_xy/public/plugin.ts b/src/plugins/vis_type_xy/public/plugin.ts index cdacc1bfaca6ae..f900234dd6052e 100644 --- a/src/plugins/vis_type_xy/public/plugin.ts +++ b/src/plugins/vis_type_xy/public/plugin.ts @@ -36,7 +36,7 @@ import { setTrackUiMetric, } from './services'; import { visTypesDefinitions } from './vis_types'; -import { LEGACY_CHARTS_LIBRARY } from '../common'; +import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_vislib/common/index'; import { xyVisRenderer } from './vis_renderer'; // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/plugins/vis_type_xy/server/index.ts b/src/plugins/vis_type_xy/server/index.ts deleted file mode 100644 index 62c8ef1876d548..00000000000000 --- a/src/plugins/vis_type_xy/server/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { VisTypeXyServerPlugin } from './plugin'; - -export const plugin = () => new VisTypeXyServerPlugin(); diff --git a/src/plugins/vis_type_xy/server/plugin.ts b/src/plugins/vis_type_xy/server/plugin.ts deleted file mode 100644 index fafc4052a88fa4..00000000000000 --- a/src/plugins/vis_type_xy/server/plugin.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; - -import { CoreSetup, Plugin, UiSettingsParams } from 'kibana/server'; - -import { LEGACY_CHARTS_LIBRARY } from '../common'; - -export const uiSettingsConfig: Record> = { - // TODO: Remove this when vis_type_vislib is removed - // https://github.com/elastic/kibana/issues/56143 - [LEGACY_CHARTS_LIBRARY]: { - name: i18n.translate('visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name', { - defaultMessage: 'Legacy charts library', - }), - value: false, - description: i18n.translate( - 'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description', - { - defaultMessage: - 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.', - } - ), - category: ['visualization'], - schema: schema.boolean(), - }, -}; - -export class VisTypeXyServerPlugin implements Plugin { - public setup(core: CoreSetup) { - core.uiSettings.register(uiSettingsConfig); - - return {}; - } - - public start() { - return {}; - } -} diff --git a/src/plugins/vis_type_xy/tsconfig.json b/src/plugins/vis_type_xy/tsconfig.json index 5cb0bc8d0bc8ed..fa44107b1bddf4 100644 --- a/src/plugins/vis_type_xy/tsconfig.json +++ b/src/plugins/vis_type_xy/tsconfig.json @@ -21,5 +21,6 @@ { "path": "../usage_collection/tsconfig.json" }, { "path": "../kibana_utils/tsconfig.json" }, { "path": "../vis_default_editor/tsconfig.json" }, + { "path": "../vis_type_vislib/tsconfig.json" }, ] } From e81c6daeaed26a9f7d64ef2957faa9daf4bb6fcb Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 14 Jan 2021 15:11:02 +0200 Subject: [PATCH 051/111] Remove cyclic dependencies --- src/plugins/vis_type_pie/common/index.ts | 20 ++++++++++++++++++++ src/plugins/vis_type_pie/kibana.json | 2 +- src/plugins/vis_type_pie/public/plugin.ts | 2 +- src/plugins/vis_type_pie/tsconfig.json | 1 - src/plugins/vis_type_vislib/kibana.json | 3 +-- src/plugins/vis_type_xy/common/index.ts | 2 ++ src/plugins/vis_type_xy/kibana.json | 2 +- src/plugins/vis_type_xy/public/plugin.ts | 2 +- src/plugins/vis_type_xy/tsconfig.json | 1 - 9 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 src/plugins/vis_type_pie/common/index.ts diff --git a/src/plugins/vis_type_pie/common/index.ts b/src/plugins/vis_type_pie/common/index.ts new file mode 100644 index 00000000000000..9b7e834d6ce0f4 --- /dev/null +++ b/src/plugins/vis_type_pie/common/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_pie/kibana.json b/src/plugins/vis_type_pie/kibana.json index 86af73ba6aef54..c2d51fba8260dd 100644 --- a/src/plugins/vis_type_pie/kibana.json +++ b/src/plugins/vis_type_pie/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"], - "requiredBundles": ["visDefaultEditor", "visTypeVislib"] + "requiredBundles": ["visDefaultEditor"] } \ No newline at end of file diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index dcb64bb6ffce41..f25396e47da0c6 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -22,7 +22,7 @@ import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup } from '../../charts/public'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; -import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_vislib/common/index'; +import { LEGACY_CHARTS_LIBRARY } from '../common'; import { createPieVisFn } from './pie_fn'; import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; diff --git a/src/plugins/vis_type_pie/tsconfig.json b/src/plugins/vis_type_pie/tsconfig.json index 6a05844dfc2b9f..f12db316f19723 100644 --- a/src/plugins/vis_type_pie/tsconfig.json +++ b/src/plugins/vis_type_pie/tsconfig.json @@ -20,6 +20,5 @@ { "path": "../visualizations/tsconfig.json" }, { "path": "../usage_collection/tsconfig.json" }, { "path": "../vis_default_editor/tsconfig.json" }, - { "path": "../vis_type_vislib/tsconfig.json" }, ] } \ No newline at end of file diff --git a/src/plugins/vis_type_vislib/kibana.json b/src/plugins/vis_type_vislib/kibana.json index c9f5360c8ad410..56dfba0aca59c0 100644 --- a/src/plugins/vis_type_vislib/kibana.json +++ b/src/plugins/vis_type_vislib/kibana.json @@ -4,6 +4,5 @@ "server": true, "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "kibanaLegacy"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeXy", "visTypePie"], - "extraPublicDirs": ["common/index"] + "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeXy", "visTypePie"] } diff --git a/src/plugins/vis_type_xy/common/index.ts b/src/plugins/vis_type_xy/common/index.ts index 201657d7265500..edee1ea3219db6 100644 --- a/src/plugins/vis_type_xy/common/index.ts +++ b/src/plugins/vis_type_xy/common/index.ts @@ -33,3 +33,5 @@ export type ChartType = $Values; * Type of xy visualizations */ export type XyVisType = ChartType | 'horizontal_bar'; + +export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_xy/kibana.json b/src/plugins/vis_type_xy/kibana.json index f38d48a6b28b26..a32b1e4d1d8b51 100644 --- a/src/plugins/vis_type_xy/kibana.json +++ b/src/plugins/vis_type_xy/kibana.json @@ -3,5 +3,5 @@ "version": "kibana", "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeVislib"] + "requiredBundles": ["kibanaUtils", "visDefaultEditor"] } diff --git a/src/plugins/vis_type_xy/public/plugin.ts b/src/plugins/vis_type_xy/public/plugin.ts index f900234dd6052e..cdacc1bfaca6ae 100644 --- a/src/plugins/vis_type_xy/public/plugin.ts +++ b/src/plugins/vis_type_xy/public/plugin.ts @@ -36,7 +36,7 @@ import { setTrackUiMetric, } from './services'; import { visTypesDefinitions } from './vis_types'; -import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_vislib/common/index'; +import { LEGACY_CHARTS_LIBRARY } from '../common'; import { xyVisRenderer } from './vis_renderer'; // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/plugins/vis_type_xy/tsconfig.json b/src/plugins/vis_type_xy/tsconfig.json index fa44107b1bddf4..5cb0bc8d0bc8ed 100644 --- a/src/plugins/vis_type_xy/tsconfig.json +++ b/src/plugins/vis_type_xy/tsconfig.json @@ -21,6 +21,5 @@ { "path": "../usage_collection/tsconfig.json" }, { "path": "../kibana_utils/tsconfig.json" }, { "path": "../vis_default_editor/tsconfig.json" }, - { "path": "../vis_type_vislib/tsconfig.json" }, ] } From 6cfed08f0fe5982be0943cc6588eb03c5607607b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 20 Jan 2021 15:23:41 +0200 Subject: [PATCH 052/111] Modify license headers --- src/plugins/vis_type_pie/jest.config.js | 21 +++++------------- .../public/components/split_chart_warning.tsx | 21 +++++------------- .../vis_type_pie/public/editor/collections.ts | 21 +++++------------- .../public/editor/components/index.tsx | 22 +++++-------------- .../public/editor/components/pie.test.tsx | 22 +++++-------------- .../public/editor/components/pie.tsx | 22 +++++-------------- .../components/truncate_labels.test.tsx | 22 +++++-------------- .../editor/components/truncate_labels.tsx | 21 +++++------------- .../vis_type_pie/public/editor/index.ts | 21 +++++------------- .../vis_type_pie/public/editor/positions.ts | 21 +++++------------- src/plugins/vis_type_pie/public/index.ts | 22 +++++-------------- src/plugins/vis_type_pie/public/mocks.ts | 22 +++++-------------- .../public/pie_component.test.tsx | 22 +++++-------------- .../vis_type_pie/public/pie_component.tsx | 21 +++++------------- .../vis_type_pie/public/pie_fn.test.ts | 21 +++++------------- src/plugins/vis_type_pie/public/pie_fn.ts | 21 +++++------------- .../vis_type_pie/public/pie_renderer.tsx | 21 +++++------------- src/plugins/vis_type_pie/public/plugin.ts | 22 +++++-------------- .../public/sample_vis.test.mocks.ts | 21 +++++------------- .../vis_type_pie/public/to_ast.test.ts | 21 +++++------------- src/plugins/vis_type_pie/public/to_ast.ts | 21 +++++------------- .../vis_type_pie/public/to_ast_esaggs.ts | 21 +++++------------- .../vis_type_pie/public/types/index.ts | 22 +++++-------------- .../vis_type_pie/public/types/types.ts | 22 +++++-------------- .../public/utils/filter_helpers.test.ts | 22 +++++-------------- .../public/utils/filter_helpers.ts | 22 +++++-------------- .../public/utils/get_color_picker.test.tsx | 22 +++++-------------- .../public/utils/get_color_picker.tsx | 21 +++++------------- .../public/utils/get_columns.test.ts | 22 +++++-------------- .../vis_type_pie/public/utils/get_columns.ts | 22 +++++-------------- .../vis_type_pie/public/utils/get_config.ts | 22 +++++-------------- .../vis_type_pie/public/utils/get_layers.ts | 22 +++++-------------- .../public/utils/get_legend_actions.tsx | 21 +++++------------- .../vis_type_pie/public/utils/index.ts | 21 +++++------------- .../vis_type_pie/public/vis_type/index.ts | 21 +++++------------- .../vis_type_pie/public/vis_type/pie.tsx | 22 +++++-------------- .../public/vis_type/split_tooltip.tsx | 21 +++++------------- 37 files changed, 203 insertions(+), 592 deletions(-) diff --git a/src/plugins/vis_type_pie/jest.config.js b/src/plugins/vis_type_pie/jest.config.js index f31a0d718d9e16..08eb9c188d4384 100644 --- a/src/plugins/vis_type_pie/jest.config.js +++ b/src/plugins/vis_type_pie/jest.config.js @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ module.exports = { diff --git a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx index eecdbfc9a1bcea..8fe7bf052fbc68 100644 --- a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx +++ b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React from 'react'; diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts index 5df4a40f3060b0..aa74925e58ffce 100644 --- a/src/plugins/vis_type_pie/public/editor/collections.ts +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index 45494c7f8a9434..30467db61a024c 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React, { lazy } from 'react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { PieVisParams, PieTypeProps } from '../../types'; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index fb1708e4072231..9e3a9947313a94 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { ReactWrapper } from 'enzyme'; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 456575c4819f9c..0b2ec0e5deeb16 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React, { useState, useEffect } from 'react'; import { METRIC_TYPE } from '@kbn/analytics'; import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx index f92beecd08a4df..3248fef4c3c7b8 100644 --- a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { ReactWrapper } from 'enzyme'; diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx index df6af3289a10d7..430ab1123a84f0 100644 --- a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React, { ChangeEvent } from 'react'; diff --git a/src/plugins/vis_type_pie/public/editor/index.ts b/src/plugins/vis_type_pie/public/editor/index.ts index 448cef980fab8c..d6c342ad6dbf54 100644 --- a/src/plugins/vis_type_pie/public/editor/index.ts +++ b/src/plugins/vis_type_pie/public/editor/index.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ export { getLegendPositions } from './positions'; diff --git a/src/plugins/vis_type_pie/public/editor/positions.ts b/src/plugins/vis_type_pie/public/editor/positions.ts index 88beac6b6b6adf..d6e24983fd28bb 100644 --- a/src/plugins/vis_type_pie/public/editor/positions.ts +++ b/src/plugins/vis_type_pie/public/editor/positions.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/index.ts b/src/plugins/vis_type_pie/public/index.ts index 2ed826079daf06..4e377a831f59bb 100644 --- a/src/plugins/vis_type_pie/public/index.ts +++ b/src/plugins/vis_type_pie/public/index.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { VisTypePiePlugin } from './plugin'; export { pieVisType } from './vis_type'; diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts index 2c0c65d7439ac7..0cf04d7e0fbcf0 100644 --- a/src/plugins/vis_type_pie/public/mocks.ts +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { Datatable } from '../../expressions/public'; import { BucketColumns, PieVisParams, LabelPositions, ValueFormats } from './types'; diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index febf803ee4385c..443f2c87de47e0 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React from 'react'; import { Settings, TooltipType, SeriesIdentifier } from '@elastic/charts'; import { chartPluginMock } from '../../charts/public/mocks'; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 9010e0a1dea22d..3e53169540945d 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React, { diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index efa3551a8baa2d..81df0e1dcd07f5 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 0bfcce22c3fb6e..1723e986cf7cea 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 79d70761e8ad68..4a47071bb5ad14 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React, { lazy } from 'react'; diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index f25396e47da0c6..324b5df185d3ba 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; diff --git a/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts index e9fa8a44209022..c952f48f07d8a6 100644 --- a/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts +++ b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ export const samplePieVis = { diff --git a/src/plugins/vis_type_pie/public/to_ast.test.ts b/src/plugins/vis_type_pie/public/to_ast.test.ts index 29065190980c0e..271e0ee6b803bd 100644 --- a/src/plugins/vis_type_pie/public/to_ast.test.ts +++ b/src/plugins/vis_type_pie/public/to_ast.test.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { Vis } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index 7dfe03fed84c9c..5be3d460c427ed 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { getVisSchemas, VisToExpressionAst } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts index 78bda37fc6975c..8eb666fdfbf0c5 100644 --- a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts +++ b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { Vis } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/types/index.ts b/src/plugins/vis_type_pie/public/types/index.ts index 2b3cf56a1f6611..cc54db82d37e7a 100644 --- a/src/plugins/vis_type_pie/public/types/index.ts +++ b/src/plugins/vis_type_pie/public/types/index.ts @@ -1,19 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + export * from './types'; diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 2740c270c36cf0..903ddd1ac01728 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { Position } from '@elastic/charts'; import { UiCounterMetricType } from '@kbn/analytics'; import { DatatableColumn, SerializedFieldFormat } from '../../../expressions/public'; diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index 03f7c8339fc45c..94c3bbcaa11bda 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { getFilterClickData, getFilterEventData } from './filter_helpers'; import { createMockBucketColumns, createMockVisData } from '../mocks'; diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 7329114f2483c0..a3a5a33b21bbf8 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { LayerValue, SeriesIdentifier } from '@elastic/charts'; import { Datatable } from '../../../expressions/public'; import { DataPublicPluginStart } from '../../../data/public'; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index e42c0dc6f17aa3..6e92513e0db827 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React from 'react'; import { LegendColorPickerProps } from '@elastic/charts'; import { EuiPopover } from '@elastic/eui'; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index d15a85e474a72c..6077e25c2283bb 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React, { BaseSyntheticEvent, useCallback } from 'react'; diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index 9eefa5895e2901..2f0ee445cfa3bf 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { getColumns } from './get_columns'; import { PieVisParams } from '../types'; import { createMockPieParams, createMockVisData } from '../mocks'; diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts index ab38c810fa6907..6e2c4ed2f927e5 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { DatatableColumn, Datatable } from '../../../expressions/public'; import { BucketColumns, PieVisParams } from '../types'; diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index ea3edc7b5d1485..77eca4790836ea 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { PartitionConfig, PartitionLayout, RecursivePartial, Theme } from '@elastic/charts'; import { LabelPositions, PieVisParams } from '../types'; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index f2e768dc52e0fb..345b0fc9765dd0 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public'; diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 3d4b565fbcac26..122e0c3d4ee968 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React, { useState } from 'react'; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 52f70fab1bdbcf..19195822b269f1 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ export { getLayers } from './get_layers'; diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index 75a1f35dd72149..0214ee029d740d 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import { getPieVisTypeDefinition } from './pie'; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index 1ccd6367215699..ec581036791b2c 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -1,21 +1,11 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ + import React from 'react'; import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; diff --git a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx index 95006864c7e653..46972900cd1d23 100644 --- a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx @@ -1,20 +1,9 @@ /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. */ import React from 'react'; From 6b9a7f242c5f3ace92e188e12a7953db6e79a13f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 20 Jan 2021 15:43:23 +0200 Subject: [PATCH 053/111] Move charts library switch to visualizations plugin --- src/plugins/vis_type_pie/common/index.ts | 9 -------- src/plugins/vis_type_pie/public/plugin.ts | 2 +- src/plugins/vis_type_vislib/common/index.ts | 1 - src/plugins/vis_type_vislib/public/plugin.ts | 2 +- .../vis_type_vislib/server/ui_settings.ts | 23 +------------------ src/plugins/vis_type_xy/common/index.ts | 2 -- src/plugins/vis_type_xy/public/plugin.ts | 2 +- .../visualizations/common/constants.ts | 1 + src/plugins/visualizations/kibana.json | 3 ++- src/plugins/visualizations/server/plugin.ts | 22 +++++++++++++++++- 10 files changed, 28 insertions(+), 39 deletions(-) delete mode 100644 src/plugins/vis_type_pie/common/index.ts diff --git a/src/plugins/vis_type_pie/common/index.ts b/src/plugins/vis_type_pie/common/index.ts deleted file mode 100644 index abb06579606635..00000000000000 --- a/src/plugins/vis_type_pie/common/index.ts +++ /dev/null @@ -1,9 +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 - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. - */ - -export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 324b5df185d3ba..8f7e11f9299279 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -12,7 +12,7 @@ import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup } from '../../charts/public'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; -import { LEGACY_CHARTS_LIBRARY } from '../common'; +import { LEGACY_CHARTS_LIBRARY } from '../../visualizations/common/constants'; import { createPieVisFn } from './pie_fn'; import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; diff --git a/src/plugins/vis_type_vislib/common/index.ts b/src/plugins/vis_type_vislib/common/index.ts index 0f22927481c7d8..8303082c4eccca 100644 --- a/src/plugins/vis_type_vislib/common/index.ts +++ b/src/plugins/vis_type_vislib/common/index.ts @@ -8,4 +8,3 @@ export const DIMMING_OPACITY_SETTING = 'visualization:dimmingOpacity'; export const HEATMAP_MAX_BUCKETS_SETTING = 'visualization:heatmap:maxBuckets'; -export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts index b5af604d3ab0f9..b7e5bf54552235 100644 --- a/src/plugins/vis_type_vislib/public/plugin.ts +++ b/src/plugins/vis_type_vislib/public/plugin.ts @@ -13,7 +13,7 @@ import { VisualizationsSetup } from '../../visualizations/public'; import { ChartsPluginSetup } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; import { KibanaLegacyStart } from '../../kibana_legacy/public'; -import { LEGACY_CHARTS_LIBRARY } from '../common'; +import { LEGACY_CHARTS_LIBRARY } from '../../visualizations/common/constants'; import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn'; import { createPieVisFn } from './pie_fn'; diff --git a/src/plugins/vis_type_vislib/server/ui_settings.ts b/src/plugins/vis_type_vislib/server/ui_settings.ts index 9ca302eccbe9b6..f74484210a5381 100644 --- a/src/plugins/vis_type_vislib/server/ui_settings.ts +++ b/src/plugins/vis_type_vislib/server/ui_settings.ts @@ -10,11 +10,7 @@ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from 'kibana/server'; -import { - DIMMING_OPACITY_SETTING, - HEATMAP_MAX_BUCKETS_SETTING, - LEGACY_CHARTS_LIBRARY, -} from '../common'; +import { DIMMING_OPACITY_SETTING, HEATMAP_MAX_BUCKETS_SETTING } from '../common'; export const uiSettings: Record = { // TODO: move this to vis_type_xy when vislib is removed @@ -51,21 +47,4 @@ export const uiSettings: Record = { category: ['visualization'], schema: schema.number(), }, - // TODO: Remove this when vis_type_vislib is removed - // https://github.com/elastic/kibana/issues/56143 - [LEGACY_CHARTS_LIBRARY]: { - name: i18n.translate('visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.name', { - defaultMessage: 'Legacy charts library', - }), - value: false, - description: i18n.translate( - 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.description', - { - defaultMessage: - 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.', - } - ), - category: ['visualization'], - schema: schema.boolean(), - }, }; diff --git a/src/plugins/vis_type_xy/common/index.ts b/src/plugins/vis_type_xy/common/index.ts index c687500c9b760f..1f97d2213e15aa 100644 --- a/src/plugins/vis_type_xy/common/index.ts +++ b/src/plugins/vis_type_xy/common/index.ts @@ -22,5 +22,3 @@ export type ChartType = $Values; * Type of xy visualizations */ export type XyVisType = ChartType | 'horizontal_bar'; - -export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/vis_type_xy/public/plugin.ts b/src/plugins/vis_type_xy/public/plugin.ts index bd0211bd945cb5..7409b833edd3c1 100644 --- a/src/plugins/vis_type_xy/public/plugin.ts +++ b/src/plugins/vis_type_xy/public/plugin.ts @@ -25,7 +25,7 @@ import { setTrackUiMetric, } from './services'; import { visTypesDefinitions } from './vis_types'; -import { LEGACY_CHARTS_LIBRARY } from '../common'; +import { LEGACY_CHARTS_LIBRARY } from '../../visualizations/common/constants'; import { xyVisRenderer } from './vis_renderer'; // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/plugins/visualizations/common/constants.ts b/src/plugins/visualizations/common/constants.ts index 53977b55eaadf9..7a6a4da4d87d7f 100644 --- a/src/plugins/visualizations/common/constants.ts +++ b/src/plugins/visualizations/common/constants.ts @@ -7,3 +7,4 @@ */ export const VISUALIZE_ENABLE_LABS_SETTING = 'visualize:enableLabs'; +export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary'; diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json index 0ced74e2733d31..939b331414166c 100644 --- a/src/plugins/visualizations/kibana.json +++ b/src/plugins/visualizations/kibana.json @@ -12,5 +12,6 @@ "savedObjects" ], "optionalPlugins": ["usageCollection"], - "requiredBundles": ["kibanaUtils", "discover"] + "requiredBundles": ["kibanaUtils", "discover"], + "extraPublicDirs": ["common/constants"] } diff --git a/src/plugins/visualizations/server/plugin.ts b/src/plugins/visualizations/server/plugin.ts index 6adc4dfc9b3c8f..864676026e972b 100644 --- a/src/plugins/visualizations/server/plugin.ts +++ b/src/plugins/visualizations/server/plugin.ts @@ -18,7 +18,7 @@ import { Logger, } from '../../../core/server'; -import { VISUALIZE_ENABLE_LABS_SETTING } from '../common/constants'; +import { VISUALIZE_ENABLE_LABS_SETTING, LEGACY_CHARTS_LIBRARY } from '../common/constants'; import { visualizationSavedObjectType } from './saved_objects'; @@ -53,6 +53,26 @@ export class VisualizationsPlugin category: ['visualization'], schema: schema.boolean(), }, + // TODO: Remove this when vis_type_vislib is removed + // https://github.com/elastic/kibana/issues/56143 + [LEGACY_CHARTS_LIBRARY]: { + name: i18n.translate( + 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.name', + { + defaultMessage: 'Legacy charts library', + } + ), + value: false, + description: i18n.translate( + 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.description', + { + defaultMessage: + 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.', + } + ), + category: ['visualization'], + schema: schema.boolean(), + }, }); if (plugins.usageCollection) { From 6fe906cde51643c8b7bfc87b4d98e2d5a65a87c8 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 25 Jan 2021 10:34:46 +0200 Subject: [PATCH 054/111] Fix i18n on the switch moved to visualizations plugin --- src/plugins/visualizations/server/plugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/visualizations/server/plugin.ts b/src/plugins/visualizations/server/plugin.ts index 864676026e972b..4c6cc898dc9e07 100644 --- a/src/plugins/visualizations/server/plugin.ts +++ b/src/plugins/visualizations/server/plugin.ts @@ -57,14 +57,14 @@ export class VisualizationsPlugin // https://github.com/elastic/kibana/issues/56143 [LEGACY_CHARTS_LIBRARY]: { name: i18n.translate( - 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.name', + 'visualizations.advancedSettings.visualization.legacyChartsLibrary.name', { defaultMessage: 'Legacy charts library', } ), value: false, description: i18n.translate( - 'visTypeVislib.advancedSettings.visualization.legacyChartsLibrary.description', + 'visualizations.advancedSettings.visualization.legacyChartsLibrary.description', { defaultMessage: 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.', From 724cd3c0bbe0b7d7392df9ffb1d3333efd401cd0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 4 Feb 2021 09:43:11 +0200 Subject: [PATCH 055/111] Update license --- src/plugins/vis_type_pie/jest.config.js | 6 +++--- .../vis_type_pie/public/components/split_chart_warning.tsx | 6 +++--- src/plugins/vis_type_pie/public/editor/collections.ts | 6 +++--- src/plugins/vis_type_pie/public/editor/components/index.tsx | 6 +++--- .../vis_type_pie/public/editor/components/pie.test.tsx | 6 +++--- src/plugins/vis_type_pie/public/editor/components/pie.tsx | 6 +++--- .../public/editor/components/truncate_labels.test.tsx | 6 +++--- .../public/editor/components/truncate_labels.tsx | 6 +++--- src/plugins/vis_type_pie/public/editor/positions.ts | 6 +++--- src/plugins/vis_type_pie/public/index.ts | 6 +++--- src/plugins/vis_type_pie/public/mocks.ts | 6 +++--- src/plugins/vis_type_pie/public/pie_component.test.tsx | 6 +++--- src/plugins/vis_type_pie/public/pie_component.tsx | 6 +++--- src/plugins/vis_type_pie/public/pie_fn.test.ts | 6 +++--- src/plugins/vis_type_pie/public/pie_fn.ts | 6 +++--- src/plugins/vis_type_pie/public/pie_renderer.tsx | 6 +++--- src/plugins/vis_type_pie/public/plugin.ts | 6 +++--- src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts | 6 +++--- src/plugins/vis_type_pie/public/to_ast.test.ts | 6 +++--- src/plugins/vis_type_pie/public/to_ast.ts | 6 +++--- src/plugins/vis_type_pie/public/to_ast_esaggs.ts | 6 +++--- src/plugins/vis_type_pie/public/types/index.ts | 6 +++--- src/plugins/vis_type_pie/public/types/types.ts | 6 +++--- .../vis_type_pie/public/utils/filter_helpers.test.ts | 6 +++--- src/plugins/vis_type_pie/public/utils/filter_helpers.ts | 6 +++--- .../vis_type_pie/public/utils/get_color_picker.test.tsx | 6 +++--- src/plugins/vis_type_pie/public/utils/get_color_picker.tsx | 6 +++--- src/plugins/vis_type_pie/public/utils/get_columns.test.ts | 6 +++--- src/plugins/vis_type_pie/public/utils/get_columns.ts | 6 +++--- src/plugins/vis_type_pie/public/utils/get_config.ts | 6 +++--- src/plugins/vis_type_pie/public/utils/get_layers.ts | 6 +++--- .../vis_type_pie/public/utils/get_legend_actions.tsx | 6 +++--- src/plugins/vis_type_pie/public/utils/index.ts | 6 +++--- src/plugins/vis_type_pie/public/vis_type/index.ts | 6 +++--- src/plugins/vis_type_pie/public/vis_type/pie.tsx | 6 +++--- src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx | 6 +++--- 36 files changed, 108 insertions(+), 108 deletions(-) diff --git a/src/plugins/vis_type_pie/jest.config.js b/src/plugins/vis_type_pie/jest.config.js index 08eb9c188d4384..e4900ef4a35c8f 100644 --- a/src/plugins/vis_type_pie/jest.config.js +++ b/src/plugins/vis_type_pie/jest.config.js @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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. */ module.exports = { diff --git a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx index 8fe7bf052fbc68..c5412360f4ca59 100644 --- a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx +++ b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/editor/collections.ts b/src/plugins/vis_type_pie/public/editor/collections.ts index aa74925e58ffce..ef83a92777d2d2 100644 --- a/src/plugins/vis_type_pie/public/editor/collections.ts +++ b/src/plugins/vis_type_pie/public/editor/collections.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/editor/components/index.tsx b/src/plugins/vis_type_pie/public/editor/components/index.tsx index 89cbd9007dc8ce..6bc31208fbdb0e 100644 --- a/src/plugins/vis_type_pie/public/editor/components/index.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/index.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { lazy } from 'react'; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index 9e3a9947313a94..6900e25302da13 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index d7b52816b369b0..9bc136e57c28ce 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { useState, useEffect } from 'react'; diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx index 3248fef4c3c7b8..1d4bb238dcb50e 100644 --- a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.test.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx index 430ab1123a84f0..e6eb56725753c6 100644 --- a/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/truncate_labels.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { ChangeEvent } from 'react'; diff --git a/src/plugins/vis_type_pie/public/editor/positions.ts b/src/plugins/vis_type_pie/public/editor/positions.ts index d6e24983fd28bb..03f4ecc2100c54 100644 --- a/src/plugins/vis_type_pie/public/editor/positions.ts +++ b/src/plugins/vis_type_pie/public/editor/positions.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/index.ts b/src/plugins/vis_type_pie/public/index.ts index 4e377a831f59bb..adf8b2d073f390 100644 --- a/src/plugins/vis_type_pie/public/index.ts +++ b/src/plugins/vis_type_pie/public/index.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { VisTypePiePlugin } from './plugin'; diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts index 0cf04d7e0fbcf0..e772c1fb3c80f3 100644 --- a/src/plugins/vis_type_pie/public/mocks.ts +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { Datatable } from '../../expressions/public'; diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index 443f2c87de47e0..b2f30f365a3604 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 3e53169540945d..26bcd31e6777c2 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index 81df0e1dcd07f5..2c32ed7d821be7 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 1723e986cf7cea..04b3c6a963e158 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 4a47071bb5ad14..9538a8cf94c88c 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { lazy } from 'react'; diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 8f7e11f9299279..8c70355ba53fc8 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; diff --git a/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts index 9025758c752996..2877553eef6c62 100644 --- a/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts +++ b/src/plugins/vis_type_pie/public/sample_vis.test.mocks.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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. */ export const samplePieVis = { diff --git a/src/plugins/vis_type_pie/public/to_ast.test.ts b/src/plugins/vis_type_pie/public/to_ast.test.ts index 271e0ee6b803bd..d33a0564c013dd 100644 --- a/src/plugins/vis_type_pie/public/to_ast.test.ts +++ b/src/plugins/vis_type_pie/public/to_ast.test.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { Vis } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index 5be3d460c427ed..54c71e49f1adeb 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { getVisSchemas, VisToExpressionAst } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts index 8eb666fdfbf0c5..9b760bd4bebcc0 100644 --- a/src/plugins/vis_type_pie/public/to_ast_esaggs.ts +++ b/src/plugins/vis_type_pie/public/to_ast_esaggs.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { Vis } from '../../visualizations/public'; diff --git a/src/plugins/vis_type_pie/public/types/index.ts b/src/plugins/vis_type_pie/public/types/index.ts index cc54db82d37e7a..12594660136d8f 100644 --- a/src/plugins/vis_type_pie/public/types/index.ts +++ b/src/plugins/vis_type_pie/public/types/index.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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. */ export * from './types'; diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 903ddd1ac01728..8c0e8c40df3a73 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { Position } from '@elastic/charts'; diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index 94c3bbcaa11bda..746cc7d0c2a351 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { getFilterClickData, getFilterEventData } from './filter_helpers'; diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index a3a5a33b21bbf8..14231f31000839 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { LayerValue, SeriesIdentifier } from '@elastic/charts'; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index 6e92513e0db827..25819fc492d648 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 6077e25c2283bb..85afef96db260f 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { BaseSyntheticEvent, useCallback } from 'react'; diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index 2f0ee445cfa3bf..ec8db536d0c59f 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { getColumns } from './get_columns'; diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts index 6e2c4ed2f927e5..e26cb7d096693b 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { DatatableColumn, Datatable } from '../../../expressions/public'; diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 77eca4790836ea..54ba64e72efa3a 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { PartitionConfig, PartitionLayout, RecursivePartial, Theme } from '@elastic/charts'; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 345b0fc9765dd0..f8786945b413f9 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { i18n } from '@kbn/i18n'; diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 122e0c3d4ee968..feb0b1dc8a6311 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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, { useState } from 'react'; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 19195822b269f1..47ff82f4d167c2 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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. */ export { getLayers } from './get_layers'; diff --git a/src/plugins/vis_type_pie/public/vis_type/index.ts b/src/plugins/vis_type_pie/public/vis_type/index.ts index 0214ee029d740d..e02e802028a352 100644 --- a/src/plugins/vis_type_pie/public/vis_type/index.ts +++ b/src/plugins/vis_type_pie/public/vis_type/index.ts @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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 { getPieVisTypeDefinition } from './pie'; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.tsx index 3e9fa67220a587..073631153aa766 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; diff --git a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx index 46972900cd1d23..b3a42da1b5477a 100644 --- a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx @@ -1,9 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * and the Server Side Public License, v 1; you may not use this file except in - * compliance with, at your election, the Elastic License or the Server Side - * Public License, v 1. + * 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'; From ca8be9f279e2894693980221095f9060870d7a9b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 15 Feb 2021 10:52:45 +0200 Subject: [PATCH 056/111] Fix tests --- src/plugins/vis_type_pie/public/pie_component.test.tsx | 2 +- .../vis_type_pie/public/utils/filter_helpers.test.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index b2f30f365a3604..a8ba1364e8c672 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -104,7 +104,7 @@ describe('PieComponent', function () { it('calls filter callback', () => { const component = shallow(); component.find(Settings).first().prop('onElementClick')!([ - [[{ groupByRollup: 6, value: 6 }], {} as SeriesIdentifier], + [[{ groupByRollup: 6, value: 6, depth: 1, path: [], sortIndex: 1 }], {} as SeriesIdentifier], ]); expect(wrapperProps.fireEvent).toHaveBeenCalled(); }); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index 746cc7d0c2a351..4df9de5fa05a70 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -18,6 +18,9 @@ describe('getFilterClickData', () => { { groupByRollup: 'Logstash Airways', value: 729, + depth: 1, + path: [], + sortIndex: 1, }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); @@ -32,6 +35,9 @@ describe('getFilterClickData', () => { { groupByRollup: 'ES-Air', value: 572, + depth: 1, + path: [], + sortIndex: 1, }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); From f19035fa63ba75758d22a7f172c2046e38e0439b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 22 Feb 2021 12:51:56 +0200 Subject: [PATCH 057/111] Fix bugs created by new charts version --- .../public/utils/get_color_picker.test.tsx | 10 ++++++---- .../vis_type_pie/public/utils/get_color_picker.tsx | 8 +++++++- .../vis_type_pie/public/utils/get_legend_actions.tsx | 8 ++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index 25819fc492d648..03f93bafdc22d3 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -45,10 +45,12 @@ describe('getColorPicker', function () { onClose: jest.fn(), onChange: jest.fn(), anchor: document.createElement('div'), - seriesIdentifier: { - key: 'Logstash Airways', - specId: 'pie', - }, + seriesIdentifiers: [ + { + key: 'Logstash Airways', + specId: 'pie', + }, + ], }; }); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 85afef96db260f..0a2483969742fd 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -55,7 +55,13 @@ export const getColorPicker = ( bucketColumns: Array>, palette: string, data: DatatableRow[] -): LegendColorPicker => ({ anchor, color, onClose, onChange, seriesIdentifier }) => { +): LegendColorPicker => ({ + anchor, + color, + onClose, + onChange, + seriesIdentifiers: [seriesIdentifier], +}) => { const seriesName = seriesIdentifier.key; const handlChange = (newColor: string | null, event: BaseSyntheticEvent) => { if (newColor) { diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index feb0b1dc8a6311..50a66f7a0ec3f1 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -26,10 +26,10 @@ export const getLegendActions = ( actions: DataPublicPluginStart['actions'], formatter: DataPublicPluginStart['fieldFormats'] ): LegendAction => { - return ({ series }) => { + return ({ series: [pieSeries] }) => { const [popoverOpen, setPopoverOpen] = useState(false); const [isfilterable, setIsfilterable] = useState(true); - const filterData = getFilterEventData(series); + const filterData = getFilterEventData(pieSeries); (async () => setIsfilterable(await canFilter(filterData, actions)))(); @@ -42,10 +42,10 @@ export const getLegendActions = ( const column = visParams.dimensions.buckets.find( (bucket) => bucket.accessor === filterData.data.data[0].column ); - formattedTitle = formatter.deserialize(column?.format).convert(series.key) ?? ''; + formattedTitle = formatter.deserialize(column?.format).convert(pieSeries.key) ?? ''; } - const title = formattedTitle || series.key; + const title = formattedTitle || pieSeries.key; const panels: EuiContextMenuPanelDescriptor[] = [ { id: 'main', From f5c6c82b6f82aab145c7aaa0eb83217e69aac6d2 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 16 Mar 2021 15:00:36 +0200 Subject: [PATCH 058/111] Fix the i18n switch problem --- src/plugins/visualizations/server/plugin.ts | 13 ++++++++----- x-pack/plugins/translations/translations/ja-JP.json | 4 ++-- x-pack/plugins/translations/translations/zh-CN.json | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/plugins/visualizations/server/plugin.ts b/src/plugins/visualizations/server/plugin.ts index fe9350b772f788..435210762293b8 100644 --- a/src/plugins/visualizations/server/plugin.ts +++ b/src/plugins/visualizations/server/plugin.ts @@ -56,13 +56,16 @@ export class VisualizationsPlugin // TODO: Remove this when vis_type_vislib is removed // https://github.com/elastic/kibana/issues/56143 [LEGACY_CHARTS_LIBRARY]: { - name: i18n.translate('visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name', { - defaultMessage: 'Legacy charts library', - }), + name: i18n.translate( + 'visualizations.advancedSettings.visualization.legacyChartsLibrary.name', + { + defaultMessage: 'Legacy charts library', + } + ), requiresPageReload: true, value: false, description: i18n.translate( - 'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description', + 'visualizations.advancedSettings.visualization.legacyChartsLibrary.description', { defaultMessage: 'Enables legacy charts library for area, line, bar, pie charts in visualize.', @@ -70,7 +73,7 @@ export class VisualizationsPlugin ), category: ['visualization'], schema: schema.boolean(), - } + }, }); if (plugins.usageCollection) { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d2023ae7a7cfa8..f5ca316211cce1 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4686,8 +4686,8 @@ "visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}、トグルオプション", "visTypeVislib.vislib.tooltip.fieldLabel": "フィールド", "visTypeVislib.vislib.tooltip.valueLabel": "値", - "visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description": "Visualizeでエリア、折れ線、棒グラフのレガシーグラフライブラリを有効にします。", - "visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name": "レガシーグラフライブラリ", + "visualizations.advancedSettings.visualization.legacyChartsLibrary.description": "Visualizeでエリア、折れ線、棒グラフのレガシーグラフライブラリを有効にします。", + "visualizations.advancedSettings.visualization.legacyChartsLibrary.name": "レガシーグラフライブラリ", "visTypeXy.aggResponse.allDocsTitle": "すべてのドキュメント", "visTypeXy.area.areaDescription": "軸と線の間のデータを強調します。", "visTypeXy.area.areaTitle": "エリア", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 501f28cd1fb27f..c01277f2a17bb6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4712,8 +4712,8 @@ "visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}, 切换选项", "visTypeVislib.vislib.tooltip.fieldLabel": "字段", "visTypeVislib.vislib.tooltip.valueLabel": "值", - "visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description": "在 Visualize 中启用面积图、折线图和条形图的旧版图表库。", - "visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name": "旧版图表库", + "visualizations.advancedSettings.visualization.legacyChartsLibrary.description": "在 Visualize 中启用面积图、折线图和条形图的旧版图表库。", + "visualizations.advancedSettings.visualization.legacyChartsLibrary.name": "旧版图表库", "visTypeXy.aggResponse.allDocsTitle": "所有文档", "visTypeXy.area.areaDescription": "突出轴与线之间的数据。", "visTypeXy.area.areaTitle": "面积图", From 8c55c5833328a39fc28cbcf443651c8709112c07 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 17 Mar 2021 13:47:42 +0200 Subject: [PATCH 059/111] Update the migration script --- .../visualization_migrations.test.ts | 69 +++++++++++-------- .../saved_objects/visualization_migrations.ts | 11 +-- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index 0b3c47769d4812..bceb8d7ca3218e 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1757,34 +1757,6 @@ describe('migration visualization', () => { }); }); - describe('7.13.0 update pie visualization defaults', () => { - const migrate = (doc: any) => - visualizationSavedObjectTypeMigrations['7.13.0']( - doc as Parameters[0], - savedObjectMigrationContext - ); - const getTestDoc = (categoryAxes?: object[], valueAxes?: object[]) => ({ - attributes: { - title: 'My Vis', - description: 'This is my super cool vis.', - visState: JSON.stringify({ - type: 'pie', - title: '[Flights] Delay Type', - params: { - type: 'pie', - }, - }), - }, - }); - - it('should decorate existing docs with the kibana legacy palette - pie', () => { - const migratedTestDoc = migrate(getTestDoc()); - const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; - - expect(palette.name).toEqual('kibana_palette'); - }); - }); - describe('7.12.0 update "schema" in aggregations', () => { const migrate = (doc: any) => visualizationSavedObjectTypeMigrations['7.12.0']( @@ -1925,4 +1897,45 @@ describe('migration visualization', () => { expect(migratedTestDoc).toEqual(expectedDoc); }); }); + + describe('7.13.0 update pie visualization defaults', () => { + const migrate = (doc: any) => + visualizationSavedObjectTypeMigrations['7.13.0']( + doc as Parameters[0], + savedObjectMigrationContext + ); + const getTestDoc = (hasPalette = false) => ({ + attributes: { + title: 'My Vis', + description: 'This is my super cool vis.', + visState: JSON.stringify({ + type: 'pie', + title: '[Flights] Delay Type', + params: { + type: 'pie', + ...(hasPalette && { + palette: { + type: 'palette', + name: 'default', + }, + }), + }, + }), + }, + }); + + it('should decorate existing docs with the kibana legacy palette if the palette is not defined - pie', () => { + const migratedTestDoc = migrate(getTestDoc()); + const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(palette.name).toEqual('kibana_palette'); + }); + + it('should not overwrite the palette with the legacy one if the palette already exists in the saved object', () => { + const migratedTestDoc = migrate(getTestDoc(true)); + const { palette } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(palette.name).toEqual('default'); + }); + }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 639b4ac14b384f..767dd5101f07c1 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -903,6 +903,7 @@ const migrateVislibPie: SavedObjectMigrationFn = (doc) => { // Let it go, the data is invalid and we'll leave it as is } if (visState && visState.type === 'pie') { + const hasPalette = visState?.params?.palette; return { ...doc, attributes: { @@ -911,10 +912,12 @@ const migrateVislibPie: SavedObjectMigrationFn = (doc) => { ...visState, params: { ...visState.params, - palette: { - type: 'palette', - name: 'kibana_palette', - }, + ...(!hasPalette && { + palette: { + type: 'palette', + name: 'kibana_palette', + }, + }), }, }), }, From da1e8e1f553172fcab67a6ed1b37b7c846d90f08 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 17 Mar 2021 15:04:56 +0200 Subject: [PATCH 060/111] Identify if colorIsOverwritten or not --- .../vis_type_pie/public/pie_component.tsx | 11 ++++++-- .../public/utils/get_color_picker.test.tsx | 28 +++++++++++++++++-- .../public/utils/get_color_picker.tsx | 7 ++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index bd5b04d4a4927e..953f272d375358 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -207,8 +207,15 @@ const PieComponent = (props: PieComponentProps) => { const legendColorPicker = useMemo( () => - getColorPicker(legendPosition, setColor, bucketColumns, visParams.palette.name, visData.rows), - [bucketColumns, legendPosition, setColor, visData.rows, visParams.palette.name] + getColorPicker( + legendPosition, + setColor, + bucketColumns, + visParams.palette.name, + visData.rows, + props.uiState + ), + [bucketColumns, legendPosition, setColor, visData.rows, visParams.palette.name, props.uiState] ); return ( diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index d985824d8ab76a..64ecf3150ab85d 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -13,6 +13,7 @@ import { mountWithIntl } from '@kbn/test/jest'; import { ComponentType, ReactWrapper } from 'enzyme'; import { getColorPicker } from './get_color_picker'; import { ColorPicker } from '../../../charts/public'; +import type { PersistedState } from '../../../visualizations/public'; import { createMockBucketColumns, createMockVisData } from '../mocks'; const bucketColumns = createMockBucketColumns(); @@ -28,13 +29,24 @@ jest.mock('@elastic/charts', () => { }); describe('getColorPicker', function () { + const mockState = new Map(); + const uiState = ({ + get: jest + .fn() + .mockImplementation((key, fallback) => (mockState.has(key) ? mockState.get(key) : fallback)), + set: jest.fn().mockImplementation((key, value) => mockState.set(key, value)), + emit: jest.fn(), + setSilent: jest.fn(), + } as unknown) as PersistedState; + let wrapperProps: LegendColorPickerProps; const Component: ComponentType = getColorPicker( 'left', jest.fn(), bucketColumns, 'default', - visData.rows + visData.rows, + uiState ); let wrapper: ReactWrapper; @@ -74,13 +86,25 @@ describe('getColorPicker', function () { expect(wrapper).toEqual({}); }); + it('renders the color picker with the colorIsOverwritten prop set to false if color is not overwritten for the specific series', () => { + wrapper = mountWithIntl(); + expect(wrapper.find(ColorPicker).prop('colorIsOverwritten')).toBe(false); + }); + + it('renders the color picker with the colorIsOverwritten prop set to true if color is overwritten for the specific series', () => { + uiState.set('vis.colors', { 'Logstash Airways': '#6092c0' }); + wrapper = mountWithIntl(); + expect(wrapper.find(ColorPicker).prop('colorIsOverwritten')).toBe(true); + }); + it('renders the picker for kibana palette and not inner layer', () => { const LegacyPaletteComponent: ComponentType = getColorPicker( 'left', jest.fn(), bucketColumns, 'kibana_palette', - visData.rows + visData.rows, + uiState ); const newProps = { ...wrapperProps, seriesIdentifier: { key: '1', specId: 'pie' } }; wrapper = mountWithIntl(); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 3aa6d5d37be406..a1f12fbba1dab1 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -11,6 +11,7 @@ import Color from 'color'; import { LegendColorPicker, Position } from '@elastic/charts'; import { PopoverAnchorPosition, EuiPopover, EuiOutsideClickDetector } from '@elastic/eui'; import { DatatableRow } from '../../../expressions/public'; +import type { PersistedState } from '../../../visualizations/public'; import { ColorPicker } from '../../../charts/public'; import { BucketColumns } from '../types'; @@ -52,7 +53,8 @@ export const getColorPicker = ( setColor: (newColor: string | null, seriesKey: string | number) => void, bucketColumns: Array>, palette: string, - data: DatatableRow[] + data: DatatableRow[], + uiState: PersistedState ): LegendColorPicker => ({ anchor, color, @@ -61,6 +63,8 @@ export const getColorPicker = ( seriesIdentifiers: [seriesIdentifier], }) => { const seriesName = seriesIdentifier.key; + const overwriteColors: Record = uiState?.get('vis.colors', {}); + const colorIsOverwritten = Object.keys(overwriteColors).includes(seriesName as string); let keyDownEventOn = false; const handleChange = (newColor: string | null) => { if (newColor) { @@ -108,6 +112,7 @@ export const getColorPicker = ( maxDepth={bucketColumns.length} layerIndex={getLayerIndex(seriesName, data, bucketColumns)} useLegacyColors={palette === 'kibana_palette'} + colorIsOverwritten={colorIsOverwritten} onKeyDown={onKeyDown} /> From cea3b376d2c8296ccc75da9fd5d5f211772dc467 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 1 Apr 2021 12:25:34 +0300 Subject: [PATCH 061/111] Small multiples, missing the click event --- package.json | 2 +- .../public/__snapshots__/pie_fn.test.ts.snap | 1 + .../public/components/chart_split.tsx | 65 +++++++++++++++++++ .../public/components/split_chart_warning.tsx | 47 -------------- .../public/editor/components/pie.test.tsx | 14 ++++ .../public/editor/components/pie.tsx | 44 +++++++++---- src/plugins/vis_type_pie/public/mocks.ts | 1 + .../vis_type_pie/public/pie_component.tsx | 57 ++++++++++++++-- .../vis_type_pie/public/pie_fn.test.ts | 1 + .../vis_type_pie/public/pie_renderer.tsx | 31 ++++----- .../vis_type_pie/public/types/types.ts | 1 + .../public/utils/filter_helpers.ts | 15 ++++- .../public/utils/get_color_picker.tsx | 4 +- .../public/utils/get_columns.test.ts | 2 + .../vis_type_pie/public/utils/get_columns.ts | 3 +- .../public/utils/get_complex_accessor.ts | 30 +++++++++ .../vis_type_pie/public/utils/get_config.ts | 1 + .../vis_type_pie/public/utils/get_layers.ts | 10 ++- .../vis_type_pie/public/utils/index.ts | 1 + .../public/vis_type/{pie.tsx => pie.ts} | 8 +-- .../public/vis_type/split_tooltip.tsx | 20 ------ yarn.lock | 8 +-- 22 files changed, 242 insertions(+), 124 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/components/chart_split.tsx delete mode 100644 src/plugins/vis_type_pie/public/components/split_chart_warning.tsx create mode 100644 src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts rename src/plugins/vis_type_pie/public/vis_type/{pie.tsx => pie.ts} (92%) delete mode 100644 src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx diff --git a/package.json b/package.json index e379123269847f..aa68125ce6e002 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "dependencies": { "@elastic/apm-rum": "^5.6.1", "@elastic/apm-rum-react": "^1.2.5", - "@elastic/charts": "26.0.0", + "@elastic/charts": "27.0.0", "@elastic/datemath": "link:packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.4", "@elastic/ems-client": "7.12.0", diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 31133d816ee90b..28e688d424a8ae 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -22,6 +22,7 @@ Object { "params": Object {}, }, }, + "flatLegend": true, "isDonut": true, "labels": Object { "last_level": true, diff --git a/src/plugins/vis_type_pie/public/components/chart_split.tsx b/src/plugins/vis_type_pie/public/components/chart_split.tsx new file mode 100644 index 00000000000000..cd4a396d5d3977 --- /dev/null +++ b/src/plugins/vis_type_pie/public/components/chart_split.tsx @@ -0,0 +1,65 @@ +/* + * 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 { Accessor, AccessorFn, GroupBy, GroupBySort, SmallMultiples } from '@elastic/charts'; +import { DatatableColumn } from '../../../expressions/public'; + +interface ChartSplitProps { + splitColumnAccessor?: Accessor | AccessorFn; + splitRowAccessor?: Accessor | AccessorFn; + splitColumn?: DatatableColumn; +} + +const CHART_SPLIT_ID = '__pie_chart_split__'; +export const SMALL_MULTIPLES_ID = '__pie_chart_sm__'; + +export const ChartSplit = ({ + splitColumnAccessor, + splitRowAccessor, + splitColumn, +}: ChartSplitProps) => { + if (!splitColumnAccessor && !splitRowAccessor) return null; + let sort: GroupBySort = 'alphaDesc'; + if (splitColumn?.meta?.params?.id === 'terms') { + sort = splitColumn?.meta?.sourceParams?.order === 'asc' ? 'alphaAsc' : 'alphaDesc'; + } + + return ( + <> + { + const splitTypeAccessor = splitColumnAccessor || splitRowAccessor; + if (splitTypeAccessor) { + return typeof splitTypeAccessor === 'function' + ? splitTypeAccessor(datum) + : datum[splitTypeAccessor]; + } + return spec.id; + }} + sort={sort} + /> + + + ); +}; diff --git a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx b/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx deleted file mode 100644 index c5412360f4ca59..00000000000000 --- a/src/plugins/vis_type_pie/public/components/split_chart_warning.tsx +++ /dev/null @@ -1,47 +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 - * 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 { EuiLink, EuiCallOut } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { DocLinksStart } from 'src/core/public'; - -interface SplitChartWarningProps { - docLinks: DocLinksStart; -} - -export function SplitChartWarning({ docLinks }: SplitChartWarningProps) { - const advancedSettingsLink = docLinks.links.management.visualizationSettings; - - return ( - - - - - ), - }} - /> - - ); -} diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index 3e3550f3dd283b..798ab80f51da2f 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -72,6 +72,20 @@ describe('PalettePicker', function () { }); }); + it('renders the flat legend switch for the elastic charts implementation', async () => { + component = mountWithIntl(); + await act(async () => { + expect(findTestSubject(component, 'visTypePieFlatLegendSwitch').length).toBe(1); + }); + }); + + it('not renders the flat legend switch for the vislib implementation', async () => { + component = mountWithIntl(); + await act(async () => { + expect(findTestSubject(component, 'visTypePieFlatLegendSwitch').length).toBe(0); + }); + }); + it('renders the label position dropdown for the elastic charts implementation', async () => { component = mountWithIntl(); await act(async () => { diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 67651192662620..575d9061e50cad 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -66,20 +66,36 @@ const PieOptions = (props: PieOptionsProps) => { /> {props.showElasticChartsOptions && ( - { - if (props.trackUiMetric) { - props.trackUiMetric(METRIC_TYPE.CLICK, 'nested_legend_switched'); - } - setValue(paramName, value); - }} - data-test-subj="visTypePieNestedLegendSwitch" - /> + <> + { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'nested_legend_switched'); + } + setValue(paramName, value); + }} + data-test-subj="visTypePieNestedLegendSwitch" + /> + { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'flat_legend_switched'); + } + setValue(paramName, value); + }} + data-test-subj="visTypePieFlatLegendSwitch" + /> + )} {props.showElasticChartsOptions && palettesRegistry && ( { }, legendPosition: 'right', nestedLegend: false, + flatLegend: true, palette: { name: 'default', type: 'palette', diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 953f272d375358..ef81ecbeea94a5 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -39,7 +39,9 @@ import { getFilterEventData, getConfig, getColumns, + getComplexAccessor, } from './utils'; +import { ChartSplit, SMALL_MULTIPLES_ID } from './components/chart_split'; import './chart.scss'; @@ -87,9 +89,10 @@ const PieComponent = (props: PieComponentProps) => { ( clickedLayers: LayerValue[], bucketColumns: Array>, - visData: Datatable + visData: Datatable, + splitChartDimension?: DatatableColumn | undefined ): void => { - const data = getFilterClickData(clickedLayers, bucketColumns, visData); + const data = getFilterClickData(clickedLayers, bucketColumns, visData, splitChartDimension); const event = { name: 'filterBucket', data: { data }, @@ -176,11 +179,24 @@ const PieComponent = (props: PieComponentProps) => { visParams, ]); + const parentSeries = useMemo(() => { + const parentBucketId = bucketColumns[0].id; + const series: string[] = []; + visData.rows.forEach((row) => { + if (!parentBucketId) return []; + if (!series.includes(row[parentBucketId])) { + series.push(row[parentBucketId]); + } + }); + return series; + }, [bucketColumns, visData.rows]); + const layers = useMemo( () => getLayers( bucketColumns, visParams, + parentSeries, props.uiState?.get('vis.colors', {}), visData.rows.length, palettesRegistry, @@ -189,11 +205,12 @@ const PieComponent = (props: PieComponentProps) => { ), [ bucketColumns, - palettesRegistry, + visParams, + parentSeries, props.uiState, - services.fieldFormats, visData.rows.length, - visParams, + palettesRegistry, + services.fieldFormats, syncColors, ] ); @@ -218,6 +235,22 @@ const PieComponent = (props: PieComponentProps) => { [bucketColumns, legendPosition, setColor, visData.rows, visParams.palette.name, props.uiState] ); + const splitChartColumnAccessor = visParams.dimensions.splitColumn + ? getComplexAccessor( + services.fieldFormats, + visData.columns + )(visParams.dimensions.splitColumn[0]) + : undefined; + const splitChartRowAccessor = visParams.dimensions.splitRow + ? getComplexAccessor(services.fieldFormats, visData.columns)(visParams.dimensions.splitRow[0]) + : undefined; + + const splitChartDimension = visParams.dimensions.splitColumn + ? visData.columns[visParams.dimensions.splitColumn[0].accessor] + : visParams.dimensions.splitRow + ? visData.columns[visParams.dimensions.splitRow[0].accessor] + : undefined; + return (
@@ -227,14 +260,25 @@ const PieComponent = (props: PieComponentProps) => { legendPosition={legendPosition} /> + { - handleSliceClick(args[0][0] as LayerValue[], bucketColumns, visData); + handleSliceClick( + args[0][0] as LayerValue[], + bucketColumns, + visData, + splitChartDimension + ); }} legendAction={getLegendActions( canFilter, @@ -250,6 +294,7 @@ const PieComponent = (props: PieComponentProps) => { /> getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index 2c32ed7d821be7..4e61a1f4e85f93 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -23,6 +23,7 @@ describe('interpreter/functions#pie', () => { legendPosition: 'right', isDonut: true, nestedLegend: true, + flatLegend: true, palette: 'kibana_palette', labels: { show: false, diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index 9538a8cf94c88c..c88b6dc97831ff 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -13,7 +13,6 @@ import { ExpressionRenderDefinition } from '../../expressions/public'; import { VisualizationContainer } from '../../visualizations/public'; import type { PersistedState } from '../../visualizations/public'; import { VisTypePieDependencies } from './plugin'; -import { SplitChartWarning } from './components/split_chart_warning'; import { RenderValue, vislibPieName } from './pie_fn'; @@ -34,7 +33,6 @@ export const getPieVisRenderer: ( reuseDomNode: true, render: async (domNode, { visConfig, visData, syncColors }, handlers) => { const showNoResult = shouldShowNoResultsMessage(visData); - const isSplitChart = Boolean(visConfig.dimensions.splitRow); handlers.onDestroy(() => { unmountComponentAtNode(domNode); @@ -44,22 +42,19 @@ export const getPieVisRenderer: ( render( - <> - {isSplitChart && } - - - - + + + , domNode ); diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 8c0e8c40df3a73..2b49dc39304f08 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -32,6 +32,7 @@ export interface PieVisParams { addLegend: boolean; legendPosition: Position; nestedLegend: boolean; + flatLegend: boolean; dimensions: Dimensions; isDonut: boolean; palette: PaletteOutput; diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 14231f31000839..56cc860c2bf333 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -7,7 +7,7 @@ */ import { LayerValue, SeriesIdentifier } from '@elastic/charts'; -import { Datatable } from '../../../expressions/public'; +import { Datatable, DatatableColumn } from '../../../expressions/public'; import { DataPublicPluginStart } from '../../../data/public'; import { ClickTriggerEvent } from '../../../charts/public'; import { ValueClickContext } from '../../../embeddable/public'; @@ -27,7 +27,8 @@ export const canFilter = async ( export const getFilterClickData = ( clickedLayers: LayerValue[], bucketColumns: Array>, - visData: Datatable + visData: Datatable, + splitChartDimension?: DatatableColumn ): ValueClickContext['data']['data'] => { const data: ValueClickContext['data']['data'] = []; const matchingIndex = visData.rows.findIndex((row) => @@ -47,6 +48,16 @@ export const getFilterClickData = ( })) ); + // console.dir(data); + // if (splitChartDimension) { + // data.push({ + // column: visData.columns.findIndex((col) => col.id === splitChartDimension.id), + // row: matchingIndex + // table: visData, + // value: + // }); + // } + return data; }; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index a1f12fbba1dab1..0202cf070847d0 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -64,7 +64,7 @@ export const getColorPicker = ( }) => { const seriesName = seriesIdentifier.key; const overwriteColors: Record = uiState?.get('vis.colors', {}); - const colorIsOverwritten = Object.keys(overwriteColors).includes(seriesName as string); + const colorIsOverwritten = Object.keys(overwriteColors).includes(seriesName.toString()); let keyDownEventOn = false; const handleChange = (newColor: string | null) => { if (newColor) { @@ -90,7 +90,7 @@ export const getColorPicker = ( // For the EuiPalette we want the user to be able to change only the colors of the inner layer if (palette !== 'kibana_palette') { - const enablePicker = isOnInnerLayer(bucketColumns[0], data, seriesName); + const enablePicker = isOnInnerLayer(bucketColumns[0], data, seriesName) || !bucketColumns[0].id; if (!enablePicker) return null; } const hexColor = new Color(color).hex(); diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index ec8db536d0c59f..75e1b7ebe471bf 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -143,6 +143,7 @@ describe('getColumns', () => { }, legendPosition: 'right', nestedLegend: false, + flatLegend: true, palette: { name: 'default', type: 'palette', @@ -167,6 +168,7 @@ describe('getColumns', () => { }, legendPosition: 'right', nestedLegend: false, + flatLegend: true, palette: { name: 'default', type: 'palette', diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts index e26cb7d096693b..77bbfeba508969 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -20,7 +20,8 @@ export const getColumns = (visParams: PieVisParams, visData: Datatable) => { const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); metricColumn = visData.columns[matchingIndex + 1]; } else { - metricColumn = visData.columns[0]; + const metricAccessor = visParams?.dimensions?.metric.accessor; + metricColumn = visData.columns[metricAccessor]; bucketColumns.push({ name: metricColumn.name, }); diff --git a/src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts b/src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts new file mode 100644 index 00000000000000..eec4f9fc09967d --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts @@ -0,0 +1,30 @@ +/* + * 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 { AccessorFn, Accessor } from '@elastic/charts'; +import { FieldFormatsStart } from '../../../data/public'; +import { DatatableColumn } from '../../../expressions/public'; +import { Dimension } from '../types'; + +export const getComplexAccessor = (fieldFormats: FieldFormatsStart, columns: DatatableColumn[]) => ( + splitDimension: Dimension +): Accessor | AccessorFn | undefined => { + const formatter = fieldFormats.deserialize(splitDimension.format); + const splitChartColumn = columns[splitDimension.accessor]; + const accessor = splitChartColumn.id; + + const fn: AccessorFn = (d) => { + const v = d[accessor]; + if (v === undefined) { + return; + } + const f = formatter.convert(v); + return f; + }; + + return fn; +}; diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 66117e933b2094..da41e28637d745 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -15,6 +15,7 @@ export const getConfig = ( ): RecursivePartial => { const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, + // clockwiseSectors: false, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, outerSizeRatio: 1, specialFirstInnermostSector: true, diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index f8786945b413f9..e53d3483584622 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -17,6 +17,7 @@ const EMPTY_SLICE = Symbol('empty_slice'); export const getLayers = ( columns: Array>, visParams: PieVisParams, + parentSeries: string[], overwriteColors: { [key: string]: string }, totalSeries: number, palettes: PaletteRegistry | null, @@ -33,6 +34,7 @@ export const getLayers = ( if (!visParams.labels.values) { fillLabel.valueFormatter = () => ''; } + const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); return columns.map((col) => { return { groupByRollup: (d: Datum) => { @@ -59,9 +61,13 @@ export const getLayers = ( // This has to be done recursively until we get to the slice index let tempParent: typeof d | typeof d['parent'] = d; while (tempParent.parent && tempParent.depth > 0) { + const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); seriesLayers.unshift({ - name: String(tempParent.parent.children[tempParent.sortIndex][0]), - rankAtDepth: tempParent.sortIndex, + name: seriesName, + rankAtDepth: + isSplitChart && parentSeries.includes(seriesName) + ? parentSeries.findIndex((name) => name === seriesName) + : tempParent.sortIndex, totalSeriesAtDepth: tempParent.parent.children.length, }); tempParent = tempParent.parent; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 47ff82f4d167c2..1ae91f07c33146 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -12,3 +12,4 @@ export { getLegendActions } from './get_legend_actions'; export { canFilter, getFilterClickData, getFilterEventData } from './filter_helpers'; export { getConfig } from './get_config'; export { getColumns } from './get_columns'; +export { getComplexAccessor } from './get_complex_accessor'; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.tsx b/src/plugins/vis_type_pie/public/vis_type/pie.ts similarity index 92% rename from src/plugins/vis_type_pie/public/vis_type/pie.tsx rename to src/plugins/vis_type_pie/public/vis_type/pie.ts index 356d1e39ce0538..58da7246b64a70 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.tsx +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import React from 'react'; import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; import { AggGroupNames } from '../../../data/public'; @@ -14,7 +13,6 @@ import { VIS_EVENT_TO_TRIGGER, VisTypeDefinition } from '../../../visualizations import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../types'; import { toExpressionAst } from '../to_ast'; import { getPieOptions } from '../editor/components'; -import { SplitTooltip } from './split_tooltip'; export const getPieVisTypeDefinition = ({ showElasticChartsOptions = false, @@ -36,6 +34,7 @@ export const getPieVisTypeDefinition = ({ addLegend: true, legendPosition: Position.Right, nestedLegend: false, + flatLegend: true, isDonut: true, palette: { type: 'palette', @@ -89,11 +88,6 @@ export const getPieVisTypeDefinition = ({ min: 0, max: 1, aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], - // TODO: Remove when split chart aggs are supported - ...(showElasticChartsOptions && { - disabled: true, - tooltip: , - }), }, ], }, diff --git a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx b/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx deleted file mode 100644 index b3a42da1b5477a..00000000000000 --- a/src/plugins/vis_type_pie/public/vis_type/split_tooltip.tsx +++ /dev/null @@ -1,20 +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 - * 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 { FormattedMessage } from '@kbn/i18n/react'; - -export function SplitTooltip() { - return ( - - ); -} diff --git a/yarn.lock b/yarn.lock index 486752dce55878..4bbc8b6d7b315c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1349,10 +1349,10 @@ dependencies: object-hash "^1.3.0" -"@elastic/charts@26.0.0": - version "26.0.0" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-26.0.0.tgz#42f06d3be0f40e0128e301b37bdfc509169c387b" - integrity sha512-5eBPSjdBb+pVDCcQOYA0dFBiYonHcw7ewxOUxgR8qMmay0xHc7gGUXZiDfIkyUDpJA+a9DS9juNNqKn/M4UbiQ== +"@elastic/charts@27.0.0": + version "27.0.0" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-27.0.0.tgz#cc6ea80dc90d07cfad0a932200cad2f6b217f7b8" + integrity sha512-gnLT+htGgcYzPUpa3NTBQyD8bw7t+0aAxdpVnBL7fZ0TdbX0xQ7u1yPEI9ljMbGguiVJMKoI1KMVLI49E3f1bg== dependencies: "@popperjs/core" "^2.4.0" chroma-js "^2.1.0" From 8d74a3f615581c9c31b00f73a506abddde88dec6 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 1 Apr 2021 16:37:14 +0300 Subject: [PATCH 062/111] Fixes the UX for small multiples part1 --- .../public/__snapshots__/pie_fn.test.ts.snap | 1 - .../public/editor/components/pie.test.tsx | 14 ----------- .../public/editor/components/pie.tsx | 25 ++++++------------- src/plugins/vis_type_pie/public/mocks.ts | 1 - .../vis_type_pie/public/pie_component.tsx | 4 +-- .../vis_type_pie/public/pie_fn.test.ts | 1 - src/plugins/vis_type_pie/public/plugin.ts | 4 +-- .../vis_type_pie/public/types/types.ts | 1 - .../public/utils/get_columns.test.ts | 2 -- .../vis_type_pie/public/utils/get_columns.ts | 2 +- .../vis_type_pie/public/utils/get_config.ts | 3 ++- .../vis_type_pie/public/vis_type/pie.ts | 3 +-- 12 files changed, 16 insertions(+), 45 deletions(-) diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 28e688d424a8ae..31133d816ee90b 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -22,7 +22,6 @@ Object { "params": Object {}, }, }, - "flatLegend": true, "isDonut": true, "labels": Object { "last_level": true, diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index 798ab80f51da2f..3e3550f3dd283b 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -72,20 +72,6 @@ describe('PalettePicker', function () { }); }); - it('renders the flat legend switch for the elastic charts implementation', async () => { - component = mountWithIntl(); - await act(async () => { - expect(findTestSubject(component, 'visTypePieFlatLegendSwitch').length).toBe(1); - }); - }); - - it('not renders the flat legend switch for the vislib implementation', async () => { - component = mountWithIntl(); - await act(async () => { - expect(findTestSubject(component, 'visTypePieFlatLegendSwitch').length).toBe(0); - }); - }); - it('renders the label position dropdown for the elastic charts implementation', async () => { component = mountWithIntl(); await act(async () => { diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 575d9061e50cad..272b1cf1bac557 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -28,13 +28,14 @@ import { getLegendPositions } from '../positions'; export interface PieOptionsProps extends VisEditorOptionsProps, PieTypeProps {} const PieOptions = (props: PieOptionsProps) => { - const { stateParams, setValue } = props; + const { stateParams, setValue, aggs } = props; const setLabels = ( paramName: T, value: PieVisParams['labels'][T] ) => setValue('labels', { ...stateParams.labels, [paramName]: value }); const [palettesRegistry, setPalettesRegistry] = useState(undefined); + const hasSplitChart = aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled); useEffect(() => { const fetchPalettes = async () => { @@ -81,20 +82,6 @@ const PieOptions = (props: PieOptionsProps) => { }} data-test-subj="visTypePieNestedLegendSwitch" /> - { - if (props.trackUiMetric) { - props.trackUiMetric(METRIC_TYPE.CLICK, 'flat_legend_switched'); - } - setValue(paramName, value); - }} - data-test-subj="visTypePieFlatLegendSwitch" - /> )} {props.showElasticChartsOptions && palettesRegistry && ( @@ -137,10 +124,14 @@ const PieOptions = (props: PieOptionsProps) => { label={i18n.translate('visTypePie.editors.pie.labelPositionLabel', { defaultMessage: 'Label position', })} - disabled={!stateParams.labels.show} + disabled={!stateParams.labels.show || Boolean(hasSplitChart)} options={getLabelPositions} paramName="position" - value={stateParams.labels.position || LabelPositions.DEFAULT} + value={ + Boolean(hasSplitChart) + ? LabelPositions.INSIDE + : stateParams.labels.position || LabelPositions.DEFAULT + } setValue={(paramName, value) => { if (props.trackUiMetric) { props.trackUiMetric(METRIC_TYPE.CLICK, 'label_position_selected'); diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts index b1e70dd3c9fe6e..e772c1fb3c80f3 100644 --- a/src/plugins/vis_type_pie/public/mocks.ts +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -278,7 +278,6 @@ export const createMockPieParams = (): PieVisParams => { }, legendPosition: 'right', nestedLegend: false, - flatLegend: true, palette: { name: 'default', type: 'palette', diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index ef81ecbeea94a5..4bc476fb6c5c95 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -62,7 +62,7 @@ const PieComponent = (props: PieComponentProps) => { const chartBaseTheme = props.chartsThemeService.useChartsBaseTheme(); const [showLegend, setShowLegend] = useState(() => { const bwcLegendStateDefault = - props.visParams.addLegend == null ? true : props.visParams.addLegend; + props.visParams.addLegend == null ? false : props.visParams.addLegend; return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); const [palettesRegistry, setPalettesRegistry] = useState(null); @@ -270,7 +270,7 @@ const PieComponent = (props: PieComponentProps) => { legendPosition={legendPosition} legendMaxDepth={visParams.nestedLegend ? undefined : 1} legendColorPicker={legendColorPicker} - flatLegend={visParams.flatLegend} + flatLegend={Boolean(splitChartDimension)} tooltip={tooltip} onElementClick={(args) => { handleSliceClick( diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index 4e61a1f4e85f93..2c32ed7d821be7 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -23,7 +23,6 @@ describe('interpreter/functions#pie', () => { legendPosition: 'right', isDonut: true, nestedLegend: true, - flatLegend: true, palette: 'kibana_palette', labels: { show: false, diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 8c70355ba53fc8..3a34e9308f4de9 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { CoreSetup, CoreStart, DocLinksStart } from 'src/core/public'; +import { CoreSetup, DocLinksStart } from 'src/core/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { ChartsPluginSetup } from '../../charts/public'; @@ -67,5 +67,5 @@ export class VisTypePiePlugin { return {}; } - start(core: CoreStart, { data }: VisTypePiePluginStartDependencies) {} + start() {} } diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 2b49dc39304f08..8c0e8c40df3a73 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -32,7 +32,6 @@ export interface PieVisParams { addLegend: boolean; legendPosition: Position; nestedLegend: boolean; - flatLegend: boolean; dimensions: Dimensions; isDonut: boolean; palette: PaletteOutput; diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index 75e1b7ebe471bf..ec8db536d0c59f 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -143,7 +143,6 @@ describe('getColumns', () => { }, legendPosition: 'right', nestedLegend: false, - flatLegend: true, palette: { name: 'default', type: 'palette', @@ -168,7 +167,6 @@ describe('getColumns', () => { }, legendPosition: 'right', nestedLegend: false, - flatLegend: true, palette: { name: 'default', type: 'palette', diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts index 77bbfeba508969..393ce9d7979d38 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -21,7 +21,7 @@ export const getColumns = (visParams: PieVisParams, visData: Datatable) => { metricColumn = visData.columns[matchingIndex + 1]; } else { const metricAccessor = visParams?.dimensions?.metric.accessor; - metricColumn = visData.columns[metricAccessor]; + metricColumn = visData.columns[metricAccessor ?? 0]; bucketColumns.push({ name: metricColumn.name, }); diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index da41e28637d745..7e56aa12b16f53 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -36,7 +36,8 @@ export const getConfig = ( // Force all labels to be linked, then prevent links from showing config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; } - if (visParams.labels.position === LabelPositions.INSIDE) { + const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); + if (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) { config.linkLabel = { maxCount: 0 }; } return config; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 58da7246b64a70..0fd72ec7ce3365 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -31,10 +31,9 @@ export const getPieVisTypeDefinition = ({ defaults: { type: 'pie', addTooltip: true, - addLegend: true, + addLegend: false, legendPosition: Position.Right, nestedLegend: false, - flatLegend: true, isDonut: true, palette: { type: 'palette', From e227e08661d93101a6cb3c2cbcb87dc66cc87d81 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 2 Apr 2021 12:34:49 +0300 Subject: [PATCH 063/111] Distinct colors per slice implementation --- .../public/__snapshots__/pie_fn.test.ts.snap | 1 + .../public/editor/components/pie.tsx | 33 ++++- src/plugins/vis_type_pie/public/mocks.ts | 1 + .../vis_type_pie/public/pie_component.tsx | 36 +++--- .../vis_type_pie/public/pie_fn.test.ts | 1 + .../vis_type_pie/public/types/types.ts | 1 + .../public/utils/get_color_picker.test.tsx | 8 +- .../public/utils/get_color_picker.tsx | 6 +- .../public/utils/get_distinct_series.ts | 32 +++++ .../vis_type_pie/public/utils/get_layers.ts | 118 ++++++++++++------ .../vis_type_pie/public/utils/index.ts | 1 + .../vis_type_pie/public/vis_type/pie.ts | 1 + 12 files changed, 176 insertions(+), 63 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/utils/get_distinct_series.ts diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 31133d816ee90b..5c2464ad3a2a38 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -22,6 +22,7 @@ Object { "params": Object {}, }, }, + "distinctColors": false, "isDonut": true, "labels": Object { "last_level": true, diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 272b1cf1bac557..30a6aaa29e3e77 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -33,10 +33,18 @@ const PieOptions = (props: PieOptionsProps) => { paramName: T, value: PieVisParams['labels'][T] ) => setValue('labels', { ...stateParams.labels, [paramName]: value }); - + const legendUiStateValue = props.uiState?.get('vis.legendOpen'); const [palettesRegistry, setPalettesRegistry] = useState(undefined); + const [legendVisibility, setLegendVisibility] = useState(() => { + const bwcLegendStateDefault = stateParams.addLegend == null ? false : stateParams.addLegend; + return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; + }); const hasSplitChart = aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled); + useEffect(() => { + setLegendVisibility(legendUiStateValue); + }, [legendUiStateValue]); + useEffect(() => { const fetchPalettes = async () => { const palettes = await props.palettes?.getPalettes(); @@ -68,6 +76,29 @@ const PieOptions = (props: PieOptionsProps) => { {props.showElasticChartsOptions && ( <> + { + setValue(paramName, value); + }} + data-test-subj="visTypePiedistinctColorsSwitch" + /> + { + setLegendVisibility(value); + setValue(paramName, value); + }} + data-test-subj="visTypePieAddLegendSwitch" + /> { }, legendPosition: 'right', nestedLegend: false, + distinctColors: false, palette: { name: 'default', type: 'palette', diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 4bc476fb6c5c95..3030444ccda9d1 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -139,6 +139,11 @@ const PieComponent = (props: PieComponentProps) => { }); }, [props.uiState]); + useEffect(() => { + setShowLegend(props.visParams.addLegend); + props.uiState?.set('vis.legendOpen', props.visParams.addLegend); + }, [props.uiState, props.visParams.addLegend]); + const setColor = useCallback( (newColor: string | null, seriesLabel: string | number) => { const colors = props.uiState?.get('vis.colors') || {}; @@ -179,26 +184,13 @@ const PieComponent = (props: PieComponentProps) => { visParams, ]); - const parentSeries = useMemo(() => { - const parentBucketId = bucketColumns[0].id; - const series: string[] = []; - visData.rows.forEach((row) => { - if (!parentBucketId) return []; - if (!series.includes(row[parentBucketId])) { - series.push(row[parentBucketId]); - } - }); - return series; - }, [bucketColumns, visData.rows]); - const layers = useMemo( () => getLayers( bucketColumns, visParams, - parentSeries, props.uiState?.get('vis.colors', {}), - visData.rows.length, + visData.rows, palettesRegistry, services.fieldFormats, syncColors @@ -206,9 +198,8 @@ const PieComponent = (props: PieComponentProps) => { [ bucketColumns, visParams, - parentSeries, props.uiState, - visData.rows.length, + visData.rows, palettesRegistry, services.fieldFormats, syncColors, @@ -230,9 +221,18 @@ const PieComponent = (props: PieComponentProps) => { bucketColumns, visParams.palette.name, visData.rows, - props.uiState + props.uiState, + visParams.distinctColors ), - [bucketColumns, legendPosition, setColor, visData.rows, visParams.palette.name, props.uiState] + [ + legendPosition, + setColor, + bucketColumns, + visParams.palette.name, + visParams.distinctColors, + visData.rows, + props.uiState, + ] ); const splitChartColumnAccessor = visParams.dimensions.splitColumn diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index 2c32ed7d821be7..b6ed95d9ae2fdc 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -23,6 +23,7 @@ describe('interpreter/functions#pie', () => { legendPosition: 'right', isDonut: true, nestedLegend: true, + distinctColors: false, palette: 'kibana_palette', labels: { show: false, diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 8c0e8c40df3a73..76f789cddcc20e 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -32,6 +32,7 @@ export interface PieVisParams { addLegend: boolean; legendPosition: Position; nestedLegend: boolean; + distinctColors: boolean; dimensions: Dimensions; isDonut: boolean; palette: PaletteOutput; diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx index 64ecf3150ab85d..5e9087947b95e7 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.test.tsx @@ -46,7 +46,8 @@ describe('getColorPicker', function () { bucketColumns, 'default', visData.rows, - uiState + uiState, + false ); let wrapper: ReactWrapper; @@ -97,14 +98,15 @@ describe('getColorPicker', function () { expect(wrapper.find(ColorPicker).prop('colorIsOverwritten')).toBe(true); }); - it('renders the picker for kibana palette and not inner layer', () => { + it('renders the picker for kibana palette and not distinctColors', () => { const LegacyPaletteComponent: ComponentType = getColorPicker( 'left', jest.fn(), bucketColumns, 'kibana_palette', visData.rows, - uiState + uiState, + true ); const newProps = { ...wrapperProps, seriesIdentifier: { key: '1', specId: 'pie' } }; wrapper = mountWithIntl(); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index 0202cf070847d0..c649bc578170cc 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -54,7 +54,8 @@ export const getColorPicker = ( bucketColumns: Array>, palette: string, data: DatatableRow[], - uiState: PersistedState + uiState: PersistedState, + distinctColors: boolean ): LegendColorPicker => ({ anchor, color, @@ -88,8 +89,7 @@ export const getColorPicker = ( onClose?.(); }, [onClose]); - // For the EuiPalette we want the user to be able to change only the colors of the inner layer - if (palette !== 'kibana_palette') { + if (!distinctColors) { const enablePicker = isOnInnerLayer(bucketColumns[0], data, seriesName) || !bucketColumns[0].id; if (!enablePicker) return null; } diff --git a/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts b/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts new file mode 100644 index 00000000000000..34df1d7103a781 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts @@ -0,0 +1,32 @@ +/* + * 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 { DatatableRow } from '../../../expressions/public'; +import { BucketColumns } from '../types'; + +export const getDistinctSeries = (rows: DatatableRow[], buckets: Array>) => { + const parentBucketId = buckets[0].id; + const parentSeries: string[] = []; + const allSeries: string[] = []; + rows.forEach((row) => { + buckets.forEach(({ id, format }) => { + if (!id) return; + // const name = format ? fieldFormats.deserialize(format).convert(row[id]) : row[id]; + const name = row[id]; + if (!allSeries.includes(name)) { + allSeries.push(name); + } + if (id === parentBucketId && !parentSeries.includes(row[parentBucketId])) { + parentSeries.push(row[parentBucketId]); + } + }); + }); + return { + allSeries, + parentSeries, + }; +}; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index e53d3483584622..1af9ff15a446a9 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -7,19 +7,86 @@ */ import { i18n } from '@kbn/i18n'; -import { Datum, PartitionFillLabel, PartitionLayer } from '@elastic/charts'; +import { Datum, PartitionFillLabel, PartitionLayer, ShapeTreeNode } from '@elastic/charts'; import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public'; import { DataPublicPluginStart } from '../../../data/public'; +import { DatatableRow } from '../../../expressions/public'; import { BucketColumns, PieVisParams } from '../types'; +import { getDistinctSeries } from './get_distinct_series'; const EMPTY_SLICE = Symbol('empty_slice'); +const computeColor = ( + d: ShapeTreeNode, + isSplitChart: boolean, + overwriteColors: { [key: string]: string }, + columns: Array>, + rows: DatatableRow[], + visParams: PieVisParams, + palettes: PaletteRegistry | null, + syncColors: boolean +) => { + const { parentSeries, allSeries } = getDistinctSeries(rows, columns); + + if (visParams.distinctColors) { + if (Object.keys(overwriteColors).includes(d.dataName.toString())) { + return overwriteColors[d.dataName]; + } + return palettes?.get(visParams.palette.name).getColor( + [ + { + name: d.dataName, + rankAtDepth: allSeries.findIndex((name) => name === d.dataName), + totalSeriesAtDepth: allSeries.length, + }, + ], + { + maxDepth: 1, + totalSeries: allSeries.length, + behindText: false, + syncColors, + } + ); + } else { + const seriesLayers: SeriesLayer[] = []; + let tempParent: typeof d | typeof d['parent'] = d; + while (tempParent.parent && tempParent.depth > 0) { + const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); + seriesLayers.unshift({ + name: seriesName, + rankAtDepth: + isSplitChart && parentSeries.includes(seriesName) + ? parentSeries.findIndex((name) => name === seriesName) + : tempParent.sortIndex, + totalSeriesAtDepth: tempParent.parent.children.length, + }); + tempParent = tempParent.parent; + } + + let overwriteColor; + seriesLayers.forEach((layer) => { + if (Object.keys(overwriteColors).includes(layer.name)) { + overwriteColor = overwriteColors[layer.name]; + } + }); + + if (overwriteColor) { + return lightenColor(overwriteColor, seriesLayers.length, columns.length); + } + return palettes?.get(visParams.palette.name).getColor(seriesLayers, { + behindText: visParams.labels.show, + maxDepth: columns.length, + totalSeries: rows.length, + syncColors, + }); + } +}; + export const getLayers = ( columns: Array>, visParams: PieVisParams, - parentSeries: string[], overwriteColors: { [key: string]: string }, - totalSeries: number, + rows: DatatableRow[], palettes: PaletteRegistry | null, formatter: DataPublicPluginStart['fieldFormats'], syncColors: boolean @@ -55,41 +122,16 @@ export const getLayers = ( fillLabel, shape: { fillColor: (d) => { - const seriesLayers: SeriesLayer[] = []; - - // Color is determined by round-robin on the index of the innermost slice - // This has to be done recursively until we get to the slice index - let tempParent: typeof d | typeof d['parent'] = d; - while (tempParent.parent && tempParent.depth > 0) { - const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); - seriesLayers.unshift({ - name: seriesName, - rankAtDepth: - isSplitChart && parentSeries.includes(seriesName) - ? parentSeries.findIndex((name) => name === seriesName) - : tempParent.sortIndex, - totalSeriesAtDepth: tempParent.parent.children.length, - }); - tempParent = tempParent.parent; - } - - let overwriteColor; - seriesLayers.forEach((layer) => { - if (Object.keys(overwriteColors).includes(layer.name)) { - overwriteColor = overwriteColors[layer.name]; - } - }); - - if (overwriteColor) { - return lightenColor(overwriteColor, seriesLayers.length, columns.length); - } - - const outputColor = palettes?.get(visParams.palette.name).getColor(seriesLayers, { - behindText: visParams.labels.show, - maxDepth: columns.length, - totalSeries, - syncColors, - }); + const outputColor = computeColor( + d, + isSplitChart, + overwriteColors, + columns, + rows, + visParams, + palettes, + syncColors + ); return outputColor || 'rgba(0,0,0,0)'; }, diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 1ae91f07c33146..19a849308bb70f 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -13,3 +13,4 @@ export { canFilter, getFilterClickData, getFilterEventData } from './filter_help export { getConfig } from './get_config'; export { getColumns } from './get_columns'; export { getComplexAccessor } from './get_complex_accessor'; +export { getDistinctSeries } from './get_distinct_series'; diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 0fd72ec7ce3365..0e253e1fcbbd14 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -34,6 +34,7 @@ export const getPieVisTypeDefinition = ({ addLegend: false, legendPosition: Position.Right, nestedLegend: false, + distinctColors: false, isDonut: true, palette: { type: 'palette', From 724eb3473a46dac99a3195452dcef466bf15c4f7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 2 Apr 2021 15:11:55 +0300 Subject: [PATCH 064/111] Fix ts references problem --- src/plugins/vis_type_pie/tsconfig.json | 2 +- tsconfig.refs.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/tsconfig.json b/src/plugins/vis_type_pie/tsconfig.json index f12db316f19723..8f829e498ede66 100644 --- a/src/plugins/vis_type_pie/tsconfig.json +++ b/src/plugins/vis_type_pie/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../tsconfig.project.json", "compilerOptions": { "composite": true, "outDir": "./target/types", diff --git a/tsconfig.refs.json b/tsconfig.refs.json index 2d9ddc1b9e5681..9a868c672ebdd0 100644 --- a/tsconfig.refs.json +++ b/tsconfig.refs.json @@ -52,6 +52,7 @@ { "path": "./src/plugins/vis_type_vislib/tsconfig.json" }, { "path": "./src/plugins/vis_type_vega/tsconfig.json" }, { "path": "./src/plugins/vis_type_xy/tsconfig.json" }, + { "path": "./src/plugins/vis_type_pie/tsconfig.json" }, { "path": "./src/plugins/visualizations/tsconfig.json" }, { "path": "./src/plugins/visualize/tsconfig.json" }, { "path": "./src/plugins/index_pattern_management/tsconfig.json" }, From 2b881f0a51b51f0291f459fe34e4ca00d9335aee Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 5 Apr 2021 12:04:16 +0300 Subject: [PATCH 065/111] Fix some small multiples bugs --- .../vis_type_pie/public/components/chart_split.tsx | 13 +++++++++---- src/plugins/vis_type_pie/public/pie_component.tsx | 2 +- .../public/utils/get_distinct_series.ts | 5 ++--- src/plugins/vis_type_pie/public/utils/get_layers.ts | 12 +++++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/plugins/vis_type_pie/public/components/chart_split.tsx b/src/plugins/vis_type_pie/public/components/chart_split.tsx index cd4a396d5d3977..b82638c06c2d3d 100644 --- a/src/plugins/vis_type_pie/public/components/chart_split.tsx +++ b/src/plugins/vis_type_pie/public/components/chart_split.tsx @@ -13,7 +13,11 @@ import { DatatableColumn } from '../../../expressions/public'; interface ChartSplitProps { splitColumnAccessor?: Accessor | AccessorFn; splitRowAccessor?: Accessor | AccessorFn; - splitColumn?: DatatableColumn; + splitDimension?: DatatableColumn; +} + +interface SplitDimensionParams { + order?: string; } const CHART_SPLIT_ID = '__pie_chart_split__'; @@ -22,12 +26,13 @@ export const SMALL_MULTIPLES_ID = '__pie_chart_sm__'; export const ChartSplit = ({ splitColumnAccessor, splitRowAccessor, - splitColumn, + splitDimension, }: ChartSplitProps) => { if (!splitColumnAccessor && !splitRowAccessor) return null; let sort: GroupBySort = 'alphaDesc'; - if (splitColumn?.meta?.params?.id === 'terms') { - sort = splitColumn?.meta?.sourceParams?.order === 'asc' ? 'alphaAsc' : 'alphaDesc'; + if (splitDimension?.meta?.params?.id === 'terms') { + const params = splitDimension?.meta?.sourceParams?.params as SplitDimensionParams; + sort = params?.order === 'asc' ? 'alphaAsc' : 'alphaDesc'; } return ( diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 3030444ccda9d1..7be3f8891aa5c8 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -263,7 +263,7 @@ const PieComponent = (props: PieComponentProps) => { { - buckets.forEach(({ id, format }) => { + buckets.forEach(({ id }) => { + rows.forEach((row) => { if (!id) return; - // const name = format ? fieldFormats.deserialize(format).convert(row[id]) : row[id]; const name = row[id]; if (!allSeries.includes(name)) { allSeries.push(name); diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 1af9ff15a446a9..3d708a6438333f 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -52,13 +52,15 @@ const computeColor = ( let tempParent: typeof d | typeof d['parent'] = d; while (tempParent.parent && tempParent.depth > 0) { const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); + const isSplitParentLayer = isSplitChart && parentSeries.includes(seriesName); seriesLayers.unshift({ name: seriesName, - rankAtDepth: - isSplitChart && parentSeries.includes(seriesName) - ? parentSeries.findIndex((name) => name === seriesName) - : tempParent.sortIndex, - totalSeriesAtDepth: tempParent.parent.children.length, + rankAtDepth: isSplitParentLayer + ? parentSeries.findIndex((name) => name === seriesName) + : tempParent.sortIndex, + totalSeriesAtDepth: isSplitParentLayer + ? parentSeries.length + : tempParent.parent.children.length, }); tempParent = tempParent.parent; } From 287b915382d4eb1ee85a2dd32cf360b4c3cacbbd Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 5 Apr 2021 15:24:20 +0300 Subject: [PATCH 066/111] Add unit tests --- .../vis_type_pie/public/utils/get_config.ts | 3 +- .../public/utils/get_distinct_series.test.ts | 30 +++++ .../public/utils/get_layers.test.ts | 114 ++++++++++++++++++ .../vis_type_pie/public/utils/get_layers.ts | 9 +- 4 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 src/plugins/vis_type_pie/public/utils/get_distinct_series.test.ts create mode 100644 src/plugins/vis_type_pie/public/utils/get_layers.test.ts diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 7e56aa12b16f53..55978519ec08eb 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -15,7 +15,6 @@ export const getConfig = ( ): RecursivePartial => { const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, - // clockwiseSectors: false, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, outerSizeRatio: 1, specialFirstInnermostSector: true, @@ -36,6 +35,8 @@ export const getConfig = ( // Force all labels to be linked, then prevent links from showing config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; } + + // On small multiples we want the labels to only appear inside const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); if (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) { config.linkLabel = { maxCount: 0 }; diff --git a/src/plugins/vis_type_pie/public/utils/get_distinct_series.test.ts b/src/plugins/vis_type_pie/public/utils/get_distinct_series.test.ts new file mode 100644 index 00000000000000..3d700614a07ed2 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_distinct_series.test.ts @@ -0,0 +1,30 @@ +/* + * 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 { getDistinctSeries } from './get_distinct_series'; +import { createMockVisData, createMockBucketColumns } from '../mocks'; + +const visData = createMockVisData(); +const buckets = createMockBucketColumns(); + +describe('getDistinctSeries', () => { + it('should return the distinct values for all buckets', () => { + const { allSeries } = getDistinctSeries(visData.rows, buckets); + expect(allSeries).toEqual(['Logstash Airways', 'JetBeats', 'ES-Air', 'Kibana Airlines', 0, 1]); + }); + + it('should return only the distinct values for the parent bucket', () => { + const { parentSeries } = getDistinctSeries(visData.rows, buckets); + expect(parentSeries).toEqual(['Logstash Airways', 'JetBeats', 'ES-Air', 'Kibana Airlines']); + }); + + it('should return empty array for empty buckets', () => { + const { parentSeries } = getDistinctSeries(visData.rows, [{ name: 'Count' }]); + expect(parentSeries.length).toEqual(0); + }); +}); diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.test.ts b/src/plugins/vis_type_pie/public/utils/get_layers.test.ts new file mode 100644 index 00000000000000..535ecbbc384b35 --- /dev/null +++ b/src/plugins/vis_type_pie/public/utils/get_layers.test.ts @@ -0,0 +1,114 @@ +/* + * 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 { ShapeTreeNode } from '@elastic/charts'; +import { PaletteDefinition, SeriesLayer } from '../../../charts/public'; +import { computeColor } from './get_layers'; +import { createMockVisData, createMockBucketColumns, createMockPieParams } from '../mocks'; + +const visData = createMockVisData(); +const buckets = createMockBucketColumns(); +const visParams = createMockPieParams(); +const colors = ['color1', 'color2', 'color3', 'color4']; +export const getPaletteRegistry = () => { + const mockPalette1: jest.Mocked = { + id: 'default', + title: 'My Palette', + getColor: jest.fn((layer: SeriesLayer[]) => colors[layer[0].rankAtDepth]), + getColors: jest.fn((num: number) => colors), + toExpression: jest.fn(() => ({ + type: 'expression', + chain: [ + { + type: 'function', + function: 'system_palette', + arguments: { + name: ['default'], + }, + }, + ], + })), + }; + + return { + get: () => mockPalette1, + getAll: () => [mockPalette1], + }; +}; + +describe('computeColor', () => { + it('should return the correct color based on the parent sortIndex', () => { + const d = ({ + dataName: 'ES-Air', + depth: 1, + sortIndex: 0, + parent: { + children: [['ES-Air'], ['Kibana Airlines']], + depth: 0, + sortIndex: 0, + }, + } as unknown) as ShapeTreeNode; + const color = computeColor( + d, + false, + {}, + buckets, + visData.rows, + visParams, + getPaletteRegistry(), + false + ); + expect(color).toEqual(colors[0]); + }); + + it('slices with the same label should have the same color for small multiples', () => { + const d = ({ + dataName: 'ES-Air', + depth: 1, + sortIndex: 0, + parent: { + children: [['ES-Air'], ['Kibana Airlines']], + depth: 0, + sortIndex: 0, + }, + } as unknown) as ShapeTreeNode; + const color = computeColor( + d, + true, + {}, + buckets, + visData.rows, + visParams, + getPaletteRegistry(), + false + ); + expect(color).toEqual('color3'); + }); + it('returns the overwriteColor if exists', () => { + const d = ({ + dataName: 'ES-Air', + depth: 1, + sortIndex: 0, + parent: { + children: [['ES-Air'], ['Kibana Airlines']], + depth: 0, + sortIndex: 0, + }, + } as unknown) as ShapeTreeNode; + const color = computeColor( + d, + true, + { 'ES-Air': '#000028' }, + buckets, + visData.rows, + visParams, + getPaletteRegistry(), + false + ); + expect(color).toEqual('#000028'); + }); +}); diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 3d708a6438333f..2e167589beef31 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -16,7 +16,7 @@ import { getDistinctSeries } from './get_distinct_series'; const EMPTY_SLICE = Symbol('empty_slice'); -const computeColor = ( +export const computeColor = ( d: ShapeTreeNode, isSplitChart: boolean, overwriteColors: { [key: string]: string }, @@ -32,17 +32,18 @@ const computeColor = ( if (Object.keys(overwriteColors).includes(d.dataName.toString())) { return overwriteColors[d.dataName]; } + const index = allSeries.findIndex((name) => name === d.dataName); return palettes?.get(visParams.palette.name).getColor( [ { name: d.dataName, - rankAtDepth: allSeries.findIndex((name) => name === d.dataName), - totalSeriesAtDepth: allSeries.length, + rankAtDepth: index > -1 ? allSeries.findIndex((name) => name === d.dataName) : 0, + totalSeriesAtDepth: allSeries.length || 1, }, ], { maxDepth: 1, - totalSeries: allSeries.length, + totalSeries: allSeries.length || 1, behindText: false, syncColors, } From f5b17874ac703a37a578b44c44c860f67eeb15fa Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 13 Apr 2021 12:46:08 +0300 Subject: [PATCH 067/111] Fix ts ref problem --- src/plugins/vis_type_pie/public/utils/get_layers.ts | 2 +- src/plugins/vis_type_pie/tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 2e167589beef31..b5d55e490d35c6 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -44,7 +44,7 @@ export const computeColor = ( { maxDepth: 1, totalSeries: allSeries.length || 1, - behindText: false, + behindText: visParams.labels.show, syncColors, } ); diff --git a/src/plugins/vis_type_pie/tsconfig.json b/src/plugins/vis_type_pie/tsconfig.json index 8f829e498ede66..f12db316f19723 100644 --- a/src/plugins/vis_type_pie/tsconfig.json +++ b/src/plugins/vis_type_pie/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.project.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "composite": true, "outDir": "./target/types", From b324340e380152617340c55966bd934bad5f5ab3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 19 Apr 2021 14:40:04 +0300 Subject: [PATCH 068/111] Fix TS problems caused by es-charts new version --- .../vis_type_pie/public/pie_component.test.tsx | 14 +++++++++++++- .../public/utils/filter_helpers.test.ts | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index a8ba1364e8c672..0f1f0b45cba734 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -104,7 +104,19 @@ describe('PieComponent', function () { it('calls filter callback', () => { const component = shallow(); component.find(Settings).first().prop('onElementClick')!([ - [[{ groupByRollup: 6, value: 6, depth: 1, path: [], sortIndex: 1 }], {} as SeriesIdentifier], + [ + [ + { + groupByRollup: 6, + value: 6, + depth: 1, + path: [], + sortIndex: 1, + smAccessorValue: 'Logstash Airways', + }, + ], + {} as SeriesIdentifier, + ], ]); expect(wrapperProps.fireEvent).toHaveBeenCalled(); }); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index 4df9de5fa05a70..187fdcc0c50697 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -21,6 +21,7 @@ describe('getFilterClickData', () => { depth: 1, path: [], sortIndex: 1, + smAccessorValue: 'Logstash Airways', }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); @@ -38,6 +39,7 @@ describe('getFilterClickData', () => { depth: 1, path: [], sortIndex: 1, + smAccessorValue: 'ES-Air', }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); From 3673e932042ce7157584963f891ee737d3986178 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 19 Apr 2021 15:12:58 +0300 Subject: [PATCH 069/111] Update the sample pie visualizations with the new eui palette --- .../services/sample_data/data_sets/ecommerce/saved_objects.ts | 2 +- .../services/sample_data/data_sets/flights/saved_objects.ts | 2 +- .../server/services/sample_data/data_sets/logs/saved_objects.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts index cfac42b97c6866..d047d89591a75d 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts @@ -45,7 +45,7 @@ export const getSavedObjects = (): SavedObject[] => [ defaultMessage: '[eCommerce] Sales by Gender', }), visState: - '{"title":"[eCommerce] Sales by Gender","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"customer_gender","size":5,"order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing"}}]}', + '{"title":"[eCommerce] Sales by Gender","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100},"palette":{"type":"palette","name":"default"}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"customer_gender","size":5,"order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing"}}]}', uiStateJSON: '{}', description: '', version: 1, diff --git a/src/plugins/home/server/services/sample_data/data_sets/flights/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/flights/saved_objects.ts index f16c1c7104417a..a79afed98c06f5 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/flights/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/flights/saved_objects.ts @@ -100,7 +100,7 @@ export const getSavedObjects = (): SavedObject[] => [ defaultMessage: '[Flights] Airline Carrier', }), visState: - '{"title":"[Flights] Airline Carrier","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"Carrier","size":5,"order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing"}}]}', + '{"title":"[Flights] Airline Carrier","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100},"palette":{"type":"palette","name":"default"}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"Carrier","size":5,"order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing"}}]}', uiStateJSON: '{"vis":{"legendOpen":false}}', description: '', version: 1, diff --git a/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts index 8a3469fe4f3c0a..35e8727216a7e8 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts @@ -234,7 +234,7 @@ export const getSavedObjects = (): SavedObject[] => [ defaultMessage: '[Logs] Visitors by OS', }), visState: - '{"title":"[Logs] Visitors by OS","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"machine.os.keyword","otherBucket":true,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","size":10,"order":"desc","orderBy":"1"}}]}', + '{"title":"[Logs] Visitors by OS","type":"pie","params":{"type":"pie","addTooltip":true,"addLegend":true,"legendPosition":"right","isDonut":true,"labels":{"show":true,"values":true,"last_level":true,"truncate":100},"palette":{"type":"palette","name":"default"}},"aggs":[{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},{"id":"2","enabled":true,"type":"terms","schema":"segment","params":{"field":"machine.os.keyword","otherBucket":true,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","size":10,"order":"desc","orderBy":"1"}}]}', uiStateJSON: '{}', description: '', version: 1, From 0784c05fbd404ab43600b3aa0375363af6f022fd Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 20 Apr 2021 14:35:05 +0300 Subject: [PATCH 070/111] Allows filtering by the small multiples value --- .../vis_type_pie/public/pie_component.tsx | 21 ++++++++++--- .../public/utils/filter_helpers.test.ts | 29 +++++++++++++++-- .../public/utils/filter_helpers.ts | 31 ++++++++++++------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 7be3f8891aa5c8..037063e44fcbf0 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -26,7 +26,7 @@ import { ChartsPluginSetup, PaletteRegistry, } from '../../charts/public'; -import { DataPublicPluginStart } from '../../data/public'; +import { DataPublicPluginStart, FieldFormat } from '../../data/public'; import type { PersistedState } from '../../visualizations/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { PieVisParams, BucketColumns, ValueFormats } from './types'; @@ -90,9 +90,16 @@ const PieComponent = (props: PieComponentProps) => { clickedLayers: LayerValue[], bucketColumns: Array>, visData: Datatable, - splitChartDimension?: DatatableColumn | undefined + splitChartDimension?: DatatableColumn, + splitChartFormatter?: FieldFormat ): void => { - const data = getFilterClickData(clickedLayers, bucketColumns, visData, splitChartDimension); + const data = getFilterClickData( + clickedLayers, + bucketColumns, + visData, + splitChartDimension, + splitChartFormatter + ); const event = { name: 'filterBucket', data: { data }, @@ -172,6 +179,11 @@ const PieComponent = (props: PieComponentProps) => { const metricFieldFormatter = services.fieldFormats.deserialize( visParams.dimensions.metric.format ); + const splitChartFormatter = visParams.dimensions.splitColumn + ? services.fieldFormats.deserialize(visParams.dimensions.splitColumn[0].format) + : visParams.dimensions.splitRow + ? services.fieldFormats.deserialize(visParams.dimensions.splitRow[0].format) + : undefined; const percentFormatter = services.fieldFormats.deserialize({ id: 'percent', params: { @@ -277,7 +289,8 @@ const PieComponent = (props: PieComponentProps) => { args[0][0] as LayerValue[], bucketColumns, visData, - splitChartDimension + splitChartDimension, + splitChartFormatter ); }} legendAction={getLegendActions( diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts index 187fdcc0c50697..3f532cf4c384ff 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.test.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - +import { DatatableColumn } from '../../../expressions/public'; import { getFilterClickData, getFilterEventData } from './filter_helpers'; import { createMockBucketColumns, createMockVisData } from '../mocks'; @@ -21,7 +21,7 @@ describe('getFilterClickData', () => { depth: 1, path: [], sortIndex: 1, - smAccessorValue: 'Logstash Airways', + smAccessorValue: '', }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); @@ -39,7 +39,7 @@ describe('getFilterClickData', () => { depth: 1, path: [], sortIndex: 1, - smAccessorValue: 'ES-Air', + smAccessorValue: '', }, ]; const data = getFilterClickData(clickedLayers, bucketColumns, visData); @@ -48,6 +48,29 @@ describe('getFilterClickData', () => { expect(data[0].row).toEqual(4); expect(data[0].column).toEqual(0); }); + + it('returns the correct filters for small multiples', () => { + const clickedLayers = [ + { + groupByRollup: 'ES-Air', + value: 572, + depth: 1, + path: [], + sortIndex: 1, + smAccessorValue: 1, + }, + ]; + const splitDimension = { + id: 'col-2-3', + name: 'Cancelled: Descending', + } as DatatableColumn; + const data = getFilterClickData(clickedLayers, bucketColumns, visData, splitDimension); + expect(data.length).toEqual(2); + expect(data[0].value).toEqual('ES-Air'); + expect(data[0].row).toEqual(5); + expect(data[0].column).toEqual(0); + expect(data[1].value).toEqual(1); + }); }); describe('getFilterEventData', () => { diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 56cc860c2bf333..77d2fedf71b6d0 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -8,7 +8,7 @@ import { LayerValue, SeriesIdentifier } from '@elastic/charts'; import { Datatable, DatatableColumn } from '../../../expressions/public'; -import { DataPublicPluginStart } from '../../../data/public'; +import { DataPublicPluginStart, FieldFormat } from '../../../data/public'; import { ClickTriggerEvent } from '../../../charts/public'; import { ValueClickContext } from '../../../embeddable/public'; import { BucketColumns } from '../types'; @@ -28,14 +28,21 @@ export const getFilterClickData = ( clickedLayers: LayerValue[], bucketColumns: Array>, visData: Datatable, - splitChartDimension?: DatatableColumn + splitChartDimension?: DatatableColumn, + splitChartFormatter?: FieldFormat ): ValueClickContext['data']['data'] => { const data: ValueClickContext['data']['data'] = []; const matchingIndex = visData.rows.findIndex((row) => clickedLayers.every((layer, index) => { const columnId = bucketColumns[index].id; if (!columnId) return; - return row[columnId] === layer.groupByRollup; + let condition = row[columnId] === layer.groupByRollup; + if (splitChartDimension) { + const value = + splitChartFormatter?.convert(row[splitChartDimension.id]) || row[splitChartDimension.id]; + condition = condition && value === layer.smAccessorValue; + } + return condition; }) ); @@ -48,15 +55,15 @@ export const getFilterClickData = ( })) ); - // console.dir(data); - // if (splitChartDimension) { - // data.push({ - // column: visData.columns.findIndex((col) => col.id === splitChartDimension.id), - // row: matchingIndex - // table: visData, - // value: - // }); - // } + // Allows filtering with the small multiples value + if (splitChartDimension) { + data.push({ + column: visData.columns.findIndex((col) => col.id === splitChartDimension.id), + row: matchingIndex, + table: visData, + value: clickedLayers[0].smAccessorValue, + }); + } return data; }; From 284c1eda7c1646eb021ddc1a358f237df578486d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 21 Apr 2021 10:27:14 +0300 Subject: [PATCH 071/111] Apply sortPredicate on partition layers --- .../public/components/chart_split.tsx | 5 +-- .../vis_type_pie/public/types/types.ts | 5 +++ .../vis_type_pie/public/utils/get_layers.ts | 31 +++++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_pie/public/components/chart_split.tsx b/src/plugins/vis_type_pie/public/components/chart_split.tsx index b82638c06c2d3d..46f841113c03d4 100644 --- a/src/plugins/vis_type_pie/public/components/chart_split.tsx +++ b/src/plugins/vis_type_pie/public/components/chart_split.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { Accessor, AccessorFn, GroupBy, GroupBySort, SmallMultiples } from '@elastic/charts'; import { DatatableColumn } from '../../../expressions/public'; +import { SplitDimensionParams } from '../types'; interface ChartSplitProps { splitColumnAccessor?: Accessor | AccessorFn; @@ -16,10 +17,6 @@ interface ChartSplitProps { splitDimension?: DatatableColumn; } -interface SplitDimensionParams { - order?: string; -} - const CHART_SPLIT_ID = '__pie_chart_split__'; export const SMALL_MULTIPLES_ID = '__pie_chart_sm__'; diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 76f789cddcc20e..bf4f3789fffba8 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -68,3 +68,8 @@ export interface PieTypeProps { palettes?: ChartsPluginSetup['palettes']; trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; } + +export interface SplitDimensionParams { + order?: string; + orderBy?: string; +} diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index b5d55e490d35c6..8fc3de999b072d 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -7,11 +7,17 @@ */ import { i18n } from '@kbn/i18n'; -import { Datum, PartitionFillLabel, PartitionLayer, ShapeTreeNode } from '@elastic/charts'; +import { + Datum, + PartitionFillLabel, + PartitionLayer, + ShapeTreeNode, + ArrayEntry, +} from '@elastic/charts'; import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public'; import { DataPublicPluginStart } from '../../../data/public'; import { DatatableRow } from '../../../expressions/public'; -import { BucketColumns, PieVisParams } from '../types'; +import { BucketColumns, PieVisParams, SplitDimensionParams } from '../types'; import { getDistinctSeries } from './get_distinct_series'; const EMPTY_SLICE = Symbol('empty_slice'); @@ -122,6 +128,27 @@ export const getLayers = ( } return String(d); }, + sortPredicate: ([name1, node1]: ArrayEntry, [name2, node2]: ArrayEntry) => { + const params = col?.meta?.sourceParams?.params as SplitDimensionParams; + const sort: string | undefined = params?.orderBy; + // metric sorting + if (sort !== '_key') { + if (params?.order === 'desc') { + return node2.value - node1.value; + } else { + return node1.value - node2.value; + } + // alphabetical sorting + } else { + if (name1 > name2) { + return params?.order === 'desc' ? -1 : 1; + } + if (name2 > name1) { + return params?.order === 'desc' ? 1 : -1; + } + } + return 0; + }, fillLabel, shape: { fillColor: (d) => { From c8a31801b72159527d6286d5b3a90b67af253de7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 21 Apr 2021 14:20:01 +0300 Subject: [PATCH 072/111] Fix vilib test --- src/plugins/vis_type_pie/public/vis_type/pie.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index 0e253e1fcbbd14..f7762c05e4672e 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -31,7 +31,7 @@ export const getPieVisTypeDefinition = ({ defaults: { type: 'pie', addTooltip: true, - addLegend: false, + addLegend: !showElasticChartsOptions, legendPosition: Position.Right, nestedLegend: false, distinctColors: false, From f2a3c87bc41463f9ed98264ecc9005479e2a29b3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 22 Apr 2021 14:41:08 +0300 Subject: [PATCH 073/111] Enable functional tests for new plugin --- .../vis_type_pie/public/pie_component.tsx | 10 ++ test/functional/apps/visualize/_pie_chart.ts | 18 ++- test/functional/apps/visualize/index.ts | 1 + .../page_objects/visualize_chart_page.ts | 109 ++++++++++-------- .../page_objects/visualize_editor_page.ts | 4 + .../services/visualizations/pie_chart.ts | 70 +++++++++-- 6 files changed, 149 insertions(+), 63 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 037063e44fcbf0..b3ee744cb39c13 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -45,6 +45,15 @@ import { ChartSplit, SMALL_MULTIPLES_ID } from './components/chart_split'; import './chart.scss'; +declare global { + interface Window { + /** + * Flag used to enable debugState on elastic charts + */ + _echDebugStateFlag?: boolean; + } +} + export interface PieComponentProps { visParams: PieVisParams; visData: Datatable; @@ -278,6 +287,7 @@ const PieComponent = (props: PieComponentProps) => { splitDimension={splitChartDimension} /> { it('should show other and missing bucket', async function () { - const expectedTableData = ['win 8', 'win xp', 'win 7', 'ios', 'Missing', 'Other']; + const expectedTableData = ['Missing', 'Other', 'ios', 'win 7', 'win 8', 'win xp']; await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); @@ -167,7 +167,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'ID', 'BR', 'Other', - ]; + ].sort(); await PageObjects.visEditor.toggleOpenEditor(2, 'false'); await PageObjects.visEditor.clickBucket('Split slices'); @@ -189,7 +189,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should show correct result with one agg disabled', async () => { - const expectedTableData = ['win 8', 'win xp', 'win 7', 'ios', 'osx']; + const expectedTableData = ['ios', 'osx', 'win 7', 'win 8', 'win xp']; await PageObjects.visEditor.clickBucket('Split slices'); await PageObjects.visEditor.selectAggregation('Terms'); @@ -206,7 +206,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visChart.waitForRenderingCount(); - const expectedTableData = ['win 8', 'win xp', 'win 7', 'ios', 'osx']; + const expectedTableData = ['ios', 'osx', 'win 7', 'win 8', 'win xp']; await pieChart.expectPieChartLabels(expectedTableData); }); @@ -275,7 +275,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'ios', 'win 8', 'osx', - ]; + ].sort(); await pieChart.expectPieChartLabels(expectedTableData); }); @@ -425,7 +425,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'CN', '360,000', 'CN', - ]; + ].sort(); + if (PageObjects.visChart.isNewLibraryChart('visTypePieChart')) { + await PageObjects.visEditor.clickOptionsTab(); + await PageObjects.visEditor.togglePieNestedLegend(); + await PageObjects.visEditor.clickDataTab(); + await PageObjects.visEditor.clickGo(); + } await PageObjects.visChart.filterLegend('CN'); await PageObjects.visChart.waitForVisualization(); await pieChart.expectPieChartLabels(expectedTableData); diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts index 747494a690c7ed..8bdcad8da9d98f 100644 --- a/test/functional/apps/visualize/index.ts +++ b/test/functional/apps/visualize/index.ts @@ -56,6 +56,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./_point_series_options')); loadTestFile(require.resolve('./_vertical_bar_chart')); loadTestFile(require.resolve('./_vertical_bar_chart_nontimeindex')); + loadTestFile(require.resolve('./_pie_chart')); }); describe('', function () { diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index 7b69101b92475c..6f49a8cd923156 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -10,7 +10,8 @@ import { Position } from '@elastic/charts'; import { FtrProviderContext } from '../ftr_provider_context'; -const elasticChartSelector = 'visTypeXyChart'; +const xyChartSelector = 'visTypeXyChart'; +const pieChartSelector = 'visTypePieChart'; export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); @@ -25,8 +26,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr const { common } = getPageObjects(['common']); class VisualizeChart { - private async getDebugState() { - return await elasticChart.getChartDebugData(elasticChartSelector); + public async getEsChartDebugState(chartSelector: string) { + return await elasticChart.getChartDebugData(chartSelector); } /** @@ -45,32 +46,32 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr /** * Is new charts library enabled and an area, line or histogram chart exists */ - private async isVisTypeXYChart(): Promise { + public async isNewLibraryChart(chartSelector: string): Promise { const enabled = await this.isNewChartsLibraryEnabled(); if (!enabled) { - log.debug(`-- isVisTypeXYChart = false`); + log.debug(`-- isNewLibraryChart = false`); return false; } - // check if enabled but not a line, area or histogram chart + // check if enabled but not a line, area, histogram or pie chart if (await find.existsByCssSelector('.visLib__chart', 1)) { const chart = await find.byCssSelector('.visLib__chart'); const chartType = await chart.getAttribute('data-vislib-chart-type'); - if (!['line', 'area', 'histogram'].includes(chartType)) { - log.debug(`-- isVisTypeXYChart = false`); + if (!['line', 'area', 'histogram', 'pie'].includes(chartType)) { + log.debug(`-- isNewLibraryChart = false`); return false; } } - if (!(await elasticChart.hasChart(elasticChartSelector, 1))) { + if (!(await elasticChart.hasChart(chartSelector, 1))) { // not be a vislib chart type - log.debug(`-- isVisTypeXYChart = false`); + log.debug(`-- isNewLibraryChart = false`); return false; } - log.debug(`-- isVisTypeXYChart = true`); + log.debug(`-- isNewLibraryChart = true`); return true; } @@ -81,7 +82,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr * @param elasticChartsValue value expected for `@elastic/charts` chart */ public async getExpectedValue(vislibValue: T, elasticChartsValue: T): Promise { - if (await this.isVisTypeXYChart()) { + if (await this.isNewLibraryChart(xyChartSelector)) { return elasticChartsValue; } @@ -89,8 +90,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getYAxisTitle() { - if (await this.isVisTypeXYChart()) { - const xAxis = (await this.getDebugState())?.axes?.y ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const xAxis = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? []; return xAxis[0]?.title; } @@ -99,8 +100,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getXAxisLabels() { - if (await this.isVisTypeXYChart()) { - const [xAxis] = (await this.getDebugState())?.axes?.x ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const [xAxis] = (await this.getEsChartDebugState(xyChartSelector))?.axes?.x ?? []; return xAxis?.labels; } @@ -112,8 +113,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getYAxisLabels() { - if (await this.isVisTypeXYChart()) { - const [yAxis] = (await this.getDebugState())?.axes?.y ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const [yAxis] = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? []; return yAxis?.labels; } @@ -125,8 +126,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getYAxisLabelsAsNumbers() { - if (await this.isVisTypeXYChart()) { - const [yAxis] = (await this.getDebugState())?.axes?.y ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const [yAxis] = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? []; return yAxis?.values; } @@ -141,8 +142,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr * Returns an array of height values */ public async getAreaChartData(dataLabel: string, axis = 'ValueAxis-1') { - if (await this.isVisTypeXYChart()) { - const areas = (await this.getDebugState())?.areas ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? []; const points = areas.find(({ name }) => name === dataLabel)?.lines.y1.points ?? []; return points.map(({ y }) => y); } @@ -183,8 +184,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr * @param dataLabel data-label value */ public async getAreaChartPaths(dataLabel: string) { - if (await this.isVisTypeXYChart()) { - const areas = (await this.getDebugState())?.areas ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? []; const path = areas.find(({ name }) => name === dataLabel)?.path ?? ''; return path.split('L'); } @@ -208,9 +209,9 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr * @param axis axis value, 'ValueAxis-1' by default */ public async getLineChartData(dataLabel = 'Count', axis = 'ValueAxis-1') { - if (await this.isVisTypeXYChart()) { + if (await this.isNewLibraryChart(xyChartSelector)) { // For now lines are rendered as areas to enable stacking - const areas = (await this.getDebugState())?.areas ?? []; + const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? []; const lines = areas.map(({ lines: { y1 }, name, color }) => ({ ...y1, name, color })); const points = lines.find(({ name }) => name === dataLabel)?.points ?? []; return points.map(({ y }) => y); @@ -248,8 +249,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr * @param axis axis value, 'ValueAxis-1' by default */ public async getBarChartData(dataLabel = 'Count', axis = 'ValueAxis-1') { - if (await this.isVisTypeXYChart()) { - const bars = (await this.getDebugState())?.bars ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const bars = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? []; const values = bars.find(({ name }) => name === dataLabel)?.bars ?? []; return values.map(({ y }) => y); } @@ -293,8 +294,9 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async toggleLegend(show = true) { - const isVisTypeXYChart = await this.isVisTypeXYChart(); - const legendSelector = isVisTypeXYChart ? '.echLegend' : '.visLegend'; + const isVisTypeXYChart = await this.isNewLibraryChart(xyChartSelector); + const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector); + const legendSelector = isVisTypeXYChart || isVisTypePieChart ? '.echLegend' : '.visLegend'; await retry.try(async () => { const isVisible = await find.existsByCssSelector(legendSelector); @@ -321,8 +323,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async doesSelectedLegendColorExist(color: string) { - if (await this.isVisTypeXYChart()) { - const items = (await this.getDebugState())?.legend?.items ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const items = (await this.getEsChartDebugState(xyChartSelector))?.legend?.items ?? []; return items.some(({ color: c }) => c === color); } @@ -330,7 +332,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async expectError() { - if (!this.isVisTypeXYChart()) { + if (!this.isNewLibraryChart(xyChartSelector)) { await testSubjects.existOrFail('vislibVisualizeError'); } } @@ -371,17 +373,25 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr public async waitForVisualization() { await this.waitForVisualizationRenderingStabilized(); - if (!(await this.isVisTypeXYChart())) { + if (!(await this.isNewLibraryChart(xyChartSelector))) { await find.byCssSelector('.visualization'); } } public async getLegendEntries() { - if (await this.isVisTypeXYChart()) { - const items = (await this.getDebugState())?.legend?.items ?? []; + const isVisTypeXYChart = await this.isNewLibraryChart(xyChartSelector); + const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector); + if (isVisTypeXYChart) { + const items = (await this.getEsChartDebugState(xyChartSelector))?.legend?.items ?? []; return items.map(({ name }) => name); } + if (isVisTypePieChart) { + const slices = + (await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? []; + return slices.map(({ name }) => name); + } + const legendEntries = await find.allByCssSelector( '.visLegend__button', defaultFindTimeout * 2 @@ -391,10 +401,10 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr ); } - public async openLegendOptionColors(name: string, chartSelector = elasticChartSelector) { + public async openLegendOptionColors(name: string, chartSelector = xyChartSelector) { await this.waitForVisualizationRenderingStabilized(); await retry.try(async () => { - if (await this.isVisTypeXYChart()) { + if (await this.isNewLibraryChart(xyChartSelector)) { const chart = await find.byCssSelector(chartSelector); const legendItemColor = await chart.findByCssSelector( `[data-ech-series-name="${name}"] .echLegendItem__color` @@ -408,7 +418,9 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr await this.waitForVisualizationRenderingStabilized(); // arbitrary color chosen, any available would do - const arbitraryColor = (await this.isVisTypeXYChart()) ? '#d36086' : '#EF843C'; + const arbitraryColor = (await this.isNewLibraryChart(xyChartSelector)) + ? '#d36086' + : '#EF843C'; const isOpen = await this.doesLegendColorChoiceExist(arbitraryColor); if (!isOpen) { throw new Error('legend color selector not open'); @@ -524,8 +536,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getRightValueAxesCount() { - if (await this.isVisTypeXYChart()) { - const yAxes = (await this.getDebugState())?.axes?.y ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const yAxes = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? []; return yAxes.filter(({ position }) => position === Position.Right).length; } const axes = await find.allByCssSelector('.visAxis__column--right g.axis'); @@ -544,8 +556,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getHistogramSeriesCount() { - if (await this.isVisTypeXYChart()) { - const bars = (await this.getDebugState())?.bars ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const bars = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? []; return bars.filter(({ visible }) => visible).length; } @@ -554,8 +566,11 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getGridLines(): Promise> { - if (await this.isVisTypeXYChart()) { - const { x, y } = (await this.getDebugState())?.axes ?? { x: [], y: [] }; + if (await this.isNewLibraryChart(xyChartSelector)) { + const { x, y } = (await this.getEsChartDebugState(xyChartSelector))?.axes ?? { + x: [], + y: [], + }; return [...x, ...y].flatMap(({ gridlines }) => gridlines); } @@ -574,8 +589,8 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async getChartValues() { - if (await this.isVisTypeXYChart()) { - const barSeries = (await this.getDebugState())?.bars ?? []; + if (await this.isNewLibraryChart(xyChartSelector)) { + const barSeries = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? []; return barSeries.filter(({ visible }) => visible).flatMap((bars) => bars.labels); } diff --git a/test/functional/page_objects/visualize_editor_page.ts b/test/functional/page_objects/visualize_editor_page.ts index 97627556abc630..bc67f5e4cb855e 100644 --- a/test/functional/page_objects/visualize_editor_page.ts +++ b/test/functional/page_objects/visualize_editor_page.ts @@ -327,6 +327,10 @@ export function VisualizeEditorPageProvider({ getService, getPageObjects }: FtrP await testSubjects.click('visualizeEditorAutoButton'); } + public async togglePieNestedLegend() { + await testSubjects.click('visTypePieNestedLegendSwitch'); + } + public async isApplyEnabled() { const applyButton = await testSubjects.find('visualizeEditorRenderButton'); return await applyButton.isEnabled(); diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index bdf26ab8a5b448..3d32f0c738ab40 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -9,7 +9,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -export function PieChartProvider({ getService }: FtrProviderContext) { +const pieChartSelector = 'visTypePieChart'; + +export function PieChartProvider({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const retry = getService('retry'); const config = getService('config'); @@ -18,21 +20,43 @@ export function PieChartProvider({ getService }: FtrProviderContext) { const find = getService('find'); const defaultFindTimeout = config.get('timeouts.find'); const panelActions = getService('dashboardPanelActions'); + const PageObjects = getPageObjects(['visChart']); return new (class PieChart { private readonly filterActionText = 'Apply filter to current view'; async clickOnPieSlice(name?: string) { log.debug(`PieChart.clickOnPieSlice(${name})`); - if (name) { - await testSubjects.click(`pieSlice-${name.split(' ').join('-')}`); + if (await PageObjects.visChart.isNewLibraryChart(pieChartSelector)) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + let sliceLabel = name || slices[0].name; + if (name === 'Other') { + sliceLabel = '__other__'; + } + const pieSlice = slices.find((slice) => slice.name === sliceLabel); + const pie = await testSubjects.find(pieChartSelector); + if (pieSlice) { + const pieSize = await pie.getSize(); + const pieHeight = pieSize.height; + const pieWidth = pieSize.width; + await pie.clickMouseButton({ + xOffset: pieSlice.coords[0] - Math.floor(pieWidth / 2), + yOffset: Math.floor(pieHeight / 2) - pieSlice.coords[1], + }); + } } else { - // If no pie slice has been provided, find the first one available. - await retry.try(async () => { - const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice'); - log.debug('Slices found:' + slices.length); - return slices[0].click(); - }); + if (name) { + await testSubjects.click(`pieSlice-${name.split(' ').join('-')}`); + } else { + // If no pie slice has been provided, find the first one available. + await retry.try(async () => { + const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice'); + log.debug('Slices found:' + slices.length); + return slices[0].click(); + }); + } } } @@ -86,6 +110,24 @@ export function PieChartProvider({ getService }: FtrProviderContext) { } async getPieChartLabels() { + if (await PageObjects.visChart.isNewLibraryChart(pieChartSelector)) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + return slices.map((slice) => { + if (slice.name === '__missing__') { + return 'Missing'; + } else if (slice.name === '__other__') { + return 'Other'; + } else if (typeof slice.name === 'number') { + // debugState of escharts returns the numbers without comma + const val = slice.name as number; + return val.toString().replace(/\B(? await chart.getAttribute('data-label')) @@ -94,6 +136,14 @@ export function PieChartProvider({ getService }: FtrProviderContext) { async getPieSliceCount() { log.debug('PieChart.getPieSliceCount'); + + if (await PageObjects.visChart.isNewLibraryChart(pieChartSelector)) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + return slices?.length; + } + const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice'); return slices.length; } @@ -110,7 +160,7 @@ export function PieChartProvider({ getService }: FtrProviderContext) { log.debug(`PieChart.expectPieChartLabels(${expectedLabels.join(',')})`); await retry.try(async () => { const pieData = await this.getPieChartLabels(); - expect(pieData).to.eql(expectedLabels); + expect(pieData.sort()).to.eql(expectedLabels); }); } })(); From cbb2e7f557b807fbcea30fb2722dc86e00b13b1e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 22 Apr 2021 17:08:45 +0300 Subject: [PATCH 074/111] Fix some functional tests --- .../vis_type_pie/public/pie_component.tsx | 2 +- .../apps/dashboard/dashboard_state.ts | 4 ++-- test/functional/apps/visualize/_pie_chart.ts | 4 ++-- .../page_objects/visualize_chart_page.ts | 5 ++++- .../services/visualizations/pie_chart.ts | 18 ++++++++++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index b3ee744cb39c13..f0e0b6b4a3a82b 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -287,7 +287,7 @@ const PieComponent = (props: PieComponentProps) => { splitDimension={splitChartDimension} /> { - if (style.indexOf('rgb(255, 255, 255)') > 0) { + if (style.indexOf('rgb(255, 255, 255)') > -1) { whitePieSliceCounts++; } }); @@ -297,7 +297,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const pieSliceStyle = await pieChart.getPieSliceStyle(`80,000`); // The default green color that was stored with the visualization before any dashboard overrides. - expect(pieSliceStyle.indexOf('rgb(87, 193, 123)')).to.be.greaterThan(0); + expect(pieSliceStyle.indexOf('rgb(87, 193, 123)')).to.be.greaterThan(-1); }); }); diff --git a/test/functional/apps/visualize/_pie_chart.ts b/test/functional/apps/visualize/_pie_chart.ts index 209354a5b8f41e..11f886c052899f 100644 --- a/test/functional/apps/visualize/_pie_chart.ts +++ b/test/functional/apps/visualize/_pie_chart.ts @@ -403,7 +403,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await inspector.close(); }); - it('should correctly filter on legend', async () => { + it('should correctly filter on legend miaou', async () => { const expectedTableData = [ '0', 'CN', @@ -426,7 +426,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { '360,000', 'CN', ].sort(); - if (PageObjects.visChart.isNewLibraryChart('visTypePieChart')) { + if (await PageObjects.visChart.isNewLibraryChart('visTypePieChart')) { await PageObjects.visEditor.clickOptionsTab(); await PageObjects.visEditor.togglePieNestedLegend(); await PageObjects.visEditor.clickDataTab(); diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index 6f49a8cd923156..f113481e4e1e6e 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -404,7 +404,10 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr public async openLegendOptionColors(name: string, chartSelector = xyChartSelector) { await this.waitForVisualizationRenderingStabilized(); await retry.try(async () => { - if (await this.isNewLibraryChart(xyChartSelector)) { + if ( + (await this.isNewLibraryChart(xyChartSelector)) || + (await this.isNewLibraryChart(pieChartSelector)) + ) { const chart = await find.byCssSelector(chartSelector); const legendItemColor = await chart.findByCssSelector( `[data-ech-series-name="${name}"] .echLegendItem__color` diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index 3d32f0c738ab40..ebe2c4cb83c556 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -86,12 +86,30 @@ export function PieChartProvider({ getService, getPageObjects }: FtrProviderCont async getPieSliceStyle(name: string) { log.debug(`VisualizePage.getPieSliceStyle(${name})`); + if (await PageObjects.visChart.isNewLibraryChart(pieChartSelector)) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + const selectedSlice = slices.filter((slice) => { + return slice.name.toString() === name.replace(',', ''); + }); + return [selectedSlice[0].color]; + } const pieSlice = await this.getPieSlice(name); return await pieSlice.getAttribute('style'); } async getAllPieSliceStyles(name: string) { log.debug(`VisualizePage.getAllPieSliceStyles(${name})`); + if (await PageObjects.visChart.isNewLibraryChart(pieChartSelector)) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + const selectedSlice = slices.filter((slice) => { + return slice.name.toString() === name.replace(',', ''); + }); + return selectedSlice.map((slice) => slice.color); + } const pieSlices = await this.getAllPieSlices(name); return await Promise.all( pieSlices.map(async (pieSlice) => await pieSlice.getAttribute('style')) From 18212f1d7895b9ba58420b4b8d91c86b83bc6dc0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 23 Apr 2021 09:00:22 +0300 Subject: [PATCH 075/111] Minor fix --- src/plugins/vis_type_pie/public/pie_component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index f0e0b6b4a3a82b..b3ee744cb39c13 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -287,7 +287,7 @@ const PieComponent = (props: PieComponentProps) => { splitDimension={splitChartDimension} /> Date: Fri, 23 Apr 2021 13:12:51 +0300 Subject: [PATCH 076/111] Fix functional tests --- test/examples/embeddables/dashboard.ts | 6 +++++- test/functional/apps/dashboard/dashboard_state.ts | 9 ++++++--- test/functional/page_objects/visualize_chart_page.ts | 10 ++++++++++ test/functional/services/visualizations/pie_chart.ts | 7 +++++++ .../drilldowns/dashboard_to_dashboard_drilldown.ts | 4 +++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/test/examples/embeddables/dashboard.ts b/test/examples/embeddables/dashboard.ts index 70e5ba115c3af8..3b22a926e638ad 100644 --- a/test/examples/embeddables/dashboard.ts +++ b/test/examples/embeddables/dashboard.ts @@ -97,7 +97,8 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const pieChart = getService('pieChart'); const browser = getService('browser'); const dashboardExpect = getService('dashboardExpect'); - const PageObjects = getPageObjects(['common']); + const elasticChart = getService('elasticChart'); + const PageObjects = getPageObjects(['common', 'visChart']); describe('dashboard container', () => { before(async () => { @@ -109,6 +110,9 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide }); it('pie charts', async () => { + if (await PageObjects.visChart.isNewChartsLibraryEnabled()) { + await elasticChart.setNewChartUiDebugFlag(); + } await pieChart.expectPieSliceCount(5); }); diff --git a/test/functional/apps/dashboard/dashboard_state.ts b/test/functional/apps/dashboard/dashboard_state.ts index b00eba314053d9..c558e82d103636 100644 --- a/test/functional/apps/dashboard/dashboard_state.ts +++ b/test/functional/apps/dashboard/dashboard_state.ts @@ -290,14 +290,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('resets a pie slice color to the original when removed', async function () { const currentUrl = await getUrlFromShare(); - const newUrl = currentUrl.replace(`vis:(colors:('80,000':%23FFFFFF))`, ''); + const newUrl = isNewChartsLibraryEnabled + ? currentUrl.replace(`'80000':%23FFFFFF`, '') + : currentUrl.replace(`vis:(colors:('80,000':%23FFFFFF))`, ''); await browser.get(newUrl.toString(), false); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async () => { - const pieSliceStyle = await pieChart.getPieSliceStyle(`80,000`); + const pieSliceStyle = await pieChart.getPieSliceStyle('80,000'); + const color = isNewChartsLibraryEnabled ? 'rgb(102, 61, 184)' : 'rgb(87, 193, 123)'; // The default green color that was stored with the visualization before any dashboard overrides. - expect(pieSliceStyle.indexOf('rgb(87, 193, 123)')).to.be.greaterThan(-1); + expect(pieSliceStyle.indexOf(color)).to.be.greaterThan(-1); }); }); diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index f113481e4e1e6e..74bf68be3d681b 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -7,6 +7,7 @@ */ import { Position } from '@elastic/charts'; +import Color from 'color'; import { FtrProviderContext } from '../ftr_provider_context'; @@ -328,6 +329,15 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr return items.some(({ color: c }) => c === color); } + if (await this.isNewLibraryChart(pieChartSelector)) { + const slices = + (await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? []; + return slices.some(({ color: c }) => { + const rgbColor = new Color(color).rgb().toString(); + return c === rgbColor; + }); + } + return await testSubjects.exists(`legendSelectedColor-${color}`); } diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index ebe2c4cb83c556..3f1b185444ca73 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -166,6 +166,13 @@ export function PieChartProvider({ getService, getPageObjects }: FtrProviderCont return slices.length; } + async expectPieSliceCountEsCharts(expectedCount: number) { + const slices = + (await PageObjects.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0] + ?.partitions ?? []; + expect(slices.length).to.be(expectedCount); + } + async expectPieSliceCount(expectedCount: number) { log.debug(`PieChart.expectPieSliceCount(${expectedCount})`); await retry.try(async () => { diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts index b891d3cce3ba09..3de336c72e0a83 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts @@ -31,6 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const security = getService('security'); const spaces = getService('spaces'); + const elasticChart = getService('elasticChart'); describe('Dashboard to dashboard drilldown', function () { describe('Create & use drilldowns', () => { @@ -211,7 +212,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await navigateWithinDashboard(async () => { await dashboardDrilldownPanelActions.clickActionByText(DRILLDOWN_TO_PIE_CHART_NAME); }); - await pieChart.expectPieSliceCount(10); + await elasticChart.setNewChartUiDebugFlag(); + await pieChart.expectPieSliceCountEsCharts(10); }); }); }); From 318b73076595f0e61f17a0ad46cd65a4b517f6f9 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 23 Apr 2021 15:28:04 +0300 Subject: [PATCH 077/111] Fix dashboard tests --- .../dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts index 3de336c72e0a83..1660bbff10d37e 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_to_dashboard_drilldown.ts @@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'settings', 'copySavedObjectsToSpace', ]); + const queryBar = getService('queryBar'); const pieChart = getService('pieChart'); const log = getService('log'); const browser = getService('browser'); @@ -213,6 +214,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboardDrilldownPanelActions.clickActionByText(DRILLDOWN_TO_PIE_CHART_NAME); }); await elasticChart.setNewChartUiDebugFlag(); + await queryBar.submitQuery(); await pieChart.expectPieSliceCountEsCharts(10); }); }); From 17e388fa1e8f80e84fb4e777294cfe757c5924f3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 23 Apr 2021 15:44:09 +0300 Subject: [PATCH 078/111] Fix all dashboard tests --- test/functional/apps/dashboard/dashboard_state.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/apps/dashboard/dashboard_state.ts b/test/functional/apps/dashboard/dashboard_state.ts index c558e82d103636..241bade418d22e 100644 --- a/test/functional/apps/dashboard/dashboard_state.ts +++ b/test/functional/apps/dashboard/dashboard_state.ts @@ -298,8 +298,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const pieSliceStyle = await pieChart.getPieSliceStyle('80,000'); - const color = isNewChartsLibraryEnabled ? 'rgb(102, 61, 184)' : 'rgb(87, 193, 123)'; - // The default green color that was stored with the visualization before any dashboard overrides. + const color = isNewChartsLibraryEnabled ? 'rgb(111, 135, 216)' : 'rgb(87, 193, 123)'; + // The default color that was stored with the visualization before any dashboard overrides. expect(pieSliceStyle.indexOf(color)).to.be.greaterThan(-1); }); }); From 101c7db4e540130355c79145933ffbbfc2c620f7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 26 Apr 2021 10:30:12 +0300 Subject: [PATCH 079/111] Apply some improvements --- .../vis_type_pie/public/pie_component.test.tsx | 4 ++-- src/plugins/vis_type_pie/public/pie_component.tsx | 15 +++------------ src/plugins/vis_type_pie/public/pie_renderer.tsx | 3 ++- .../visualization_migrations.test.ts | 13 +++++++++++++ .../saved_objects/visualization_migrations.ts | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.test.tsx b/src/plugins/vis_type_pie/public/pie_component.test.tsx index 0f1f0b45cba734..177396f25adb67 100644 --- a/src/plugins/vis_type_pie/public/pie_component.test.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.test.tsx @@ -26,7 +26,7 @@ jest.mock('@elastic/charts', () => { }); const chartsThemeService = chartPluginMock.createSetupContract().theme; -const palettes = chartPluginMock.createSetupContract().palettes; +const palettesRegistry = chartPluginMock.createPaletteRegistry(); const visParams = createMockPieParams(); const visData = createMockVisData(); @@ -46,7 +46,7 @@ describe('PieComponent', function () { beforeAll(() => { wrapperProps = { chartsThemeService, - palettes, + palettesRegistry, visParams, visData, uiState, diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index b3ee744cb39c13..92a3d9c5696e6a 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -61,7 +61,7 @@ export interface PieComponentProps { fireEvent: IInterpreterRenderHandlers['event']; renderComplete: IInterpreterRenderHandlers['done']; chartsThemeService: ChartsPluginSetup['theme']; - palettes: ChartsPluginSetup['palettes']; + palettesRegistry: PaletteRegistry; services: DataPublicPluginStart; syncColors: boolean; } @@ -74,7 +74,6 @@ const PieComponent = (props: PieComponentProps) => { props.visParams.addLegend == null ? false : props.visParams.addLegend; return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); - const [palettesRegistry, setPalettesRegistry] = useState(null); const onRenderChange = useCallback( (isRendered) => { @@ -85,14 +84,6 @@ const PieComponent = (props: PieComponentProps) => { [props] ); - useEffect(() => { - const fetchPalettes = async () => { - const palettes = await props.palettes.getPalettes(); - setPalettesRegistry(palettes); - }; - fetchPalettes(); - }, [props.palettes]); - // handles slice click event const handleSliceClick = useCallback( ( @@ -212,7 +203,7 @@ const PieComponent = (props: PieComponentProps) => { visParams, props.uiState?.get('vis.colors', {}), visData.rows, - palettesRegistry, + props.palettesRegistry, services.fieldFormats, syncColors ), @@ -220,8 +211,8 @@ const PieComponent = (props: PieComponentProps) => { bucketColumns, visParams, props.uiState, + props.palettesRegistry, visData.rows, - palettesRegistry, services.fieldFormats, syncColors, ] diff --git a/src/plugins/vis_type_pie/public/pie_renderer.tsx b/src/plugins/vis_type_pie/public/pie_renderer.tsx index c88b6dc97831ff..bcd4cad4efa66f 100644 --- a/src/plugins/vis_type_pie/public/pie_renderer.tsx +++ b/src/plugins/vis_type_pie/public/pie_renderer.tsx @@ -39,13 +39,14 @@ export const getPieVisRenderer: ( }); const services = await getStartDeps(); + const palettesRegistry = await palettes.getPalettes(); render( { }, }); + it('should return original doc if not area, line or histogram chart', () => { + const doc = getTestDoc('pie'); + const migratedTestDoc = migrate(doc); + expect(migratedTestDoc).toEqual(doc); + }); + it('should decorate existing docs with isVislibVis flag', () => { const migratedTestDoc = migrate(getTestDoc()); const { isVislibVis } = JSON.parse(migratedTestDoc.attributes.visState).params; @@ -2011,5 +2017,12 @@ describe('migration visualization', () => { expect(palette.name).toEqual('default'); }); + + it('should default the distinct colors per slice setting to true', () => { + const migratedTestDoc = migrate(getTestDoc()); + const { distinctColors } = JSON.parse(migratedTestDoc.attributes.visState).params; + + expect(distinctColors).toBe(true); + }); }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index ef12ae5438208a..950734e17b17c4 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -1008,6 +1008,7 @@ const migrateVislibPie: SavedObjectMigrationFn = (doc) => { name: 'kibana_palette', }, }), + distinctColors: true, }, }), }, From 613b14131b07a5bf0e828851ae7873155c0b098b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 26 Apr 2021 15:38:36 +0300 Subject: [PATCH 080/111] Explicit params instead of visConfig Json --- .../public/__snapshots__/pie_fn.test.ts.snap | 21 +++- .../public/__snapshots__/to_ast.test.ts.snap | 18 +-- .../public/editor/components/pie.tsx | 4 +- .../vis_type_pie/public/pie_fn.test.ts | 18 ++- src/plugins/vis_type_pie/public/pie_fn.ts | 105 ++++++++++++++++-- src/plugins/vis_type_pie/public/to_ast.ts | 59 +++++++--- .../vis_type_pie/public/types/types.ts | 39 +++++-- .../public/expression_functions/pie_labels.ts | 103 +++++++++++++++++ src/plugins/visualizations/public/index.ts | 1 + src/plugins/visualizations/public/plugin.ts | 2 + 10 files changed, 300 insertions(+), 70 deletions(-) create mode 100644 src/plugins/visualizations/public/expression_functions/pie_labels.ts diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index 5c2464ad3a2a38..bedac0b062b6b9 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -12,7 +12,9 @@ Object { "visConfig": Object { "addLegend": true, "addTooltip": true, + "buckets": undefined, "dimensions": Object { + "buckets": undefined, "metric": Object { "accessor": 0, "aggType": "count", @@ -21,11 +23,12 @@ Object { }, "params": Object {}, }, + "splitColumn": undefined, + "splitRow": undefined, }, "distinctColors": false, "isDonut": true, "labels": Object { - "last_level": true, "position": "default", "show": false, "truncate": 100, @@ -33,9 +36,21 @@ Object { "valuesFormat": "percent", }, "legendPosition": "right", + "metric": Object { + "accessor": 0, + "aggType": "count", + "format": Object { + "id": "number", + }, + "params": Object {}, + }, "nestedLegend": true, - "palette": "kibana_palette", - "type": "pie", + "palette": Object { + "name": "kibana_palette", + "type": "palette", + }, + "splitColumn": undefined, + "splitRow": undefined, }, "visData": Object { "columns": Array [ diff --git a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap index 54607960b2e8a6..c8cc6192ca1418 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap @@ -1,19 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`pie vis toExpressionAst function should match basic snapshot 1`] = ` -Object { - "addArgument": [Function], - "arguments": Object { - "visConfig": Array [ - "{\\"type\\":\\"pie\\",\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"right\\",\\"isDonut\\":true,\\"labels\\":{\\"show\\":true,\\"values\\":true,\\"last_level\\":true,\\"truncate\\":100},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\"},\\"params\\":{}},\\"buckets\\":[{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}", - ], - }, - "getArgument": [Function], - "name": "pie_vis", - "removeArgument": [Function], - "replaceArgument": [Function], - "toAst": [Function], - "toString": [Function], - "type": "expression_function_builder", -} -`; +exports[`pie vis toExpressionAst function should match basic snapshot 1`] = `undefined`; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 30a6aaa29e3e77..860026450cab72 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -82,9 +82,7 @@ const PieOptions = (props: PieOptionsProps) => { })} paramName="distinctColors" value={stateParams.distinctColors} - setValue={(paramName, value) => { - setValue(paramName, value); - }} + setValue={setValue} data-test-subj="visTypePiedistinctColorsSwitch" /> { columns: [{ id: 'col-0-1', name: 'Count' }], }; const visConfig = { - type: 'pie', addTooltip: true, addLegend: true, legendPosition: 'right', @@ -28,20 +27,17 @@ describe('interpreter/functions#pie', () => { labels: { show: false, values: true, - last_level: true, position: 'default', valuesFormat: 'percent', truncate: 100, }, - dimensions: { - metric: { - accessor: 0, - format: { - id: 'number', - }, - params: {}, - aggType: 'count', + metric: { + accessor: 0, + format: { + id: 'number', }, + params: {}, + aggType: 'count', }, }; @@ -50,7 +46,7 @@ describe('interpreter/functions#pie', () => { }); it('returns an object with the correct structure', async () => { - const actual = await fn(context, { visConfig: JSON.stringify(visConfig) }); + const actual = await fn(context, visConfig); expect(actual).toMatchSnapshot(); }); }); diff --git a/src/plugins/vis_type_pie/public/pie_fn.ts b/src/plugins/vis_type_pie/public/pie_fn.ts index 04b3c6a963e158..1b5b8574f93117 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.ts @@ -8,14 +8,10 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; -import { PieVisParams } from './types'; +import { PieVisParams, PieVisConfig } from './types'; export const vislibPieName = 'pie_vis'; -interface Arguments { - visConfig: string; -} - export interface RenderValue { visData: Datatable; visType: string; @@ -26,7 +22,7 @@ export interface RenderValue { export type VisTypePieExpressionFunctionDefinition = ExpressionFunctionDefinition< typeof vislibPieName, Datatable, - Arguments, + PieVisConfig, Render >; @@ -38,14 +34,103 @@ export const createPieVisFn = (): VisTypePieExpressionFunctionDefinition => ({ defaultMessage: 'Pie visualization', }), args: { - visConfig: { + metric: { + types: ['vis_dimension'], + help: i18n.translate('visTypePie.function.args.metricHelpText', { + defaultMessage: 'Metric dimensions config', + }), + required: true, + }, + buckets: { + types: ['vis_dimension'], + help: i18n.translate('visTypePie.function.args.bucketsHelpText', { + defaultMessage: 'Buckets dimensions config', + }), + multi: true, + }, + splitColumn: { + types: ['vis_dimension'], + help: i18n.translate('visTypePie.function.args.splitColumnHelpText', { + defaultMessage: 'Split by column dimension config', + }), + multi: true, + }, + splitRow: { + types: ['vis_dimension'], + help: i18n.translate('visTypePie.function.args.splitRowHelpText', { + defaultMessage: 'Split by row dimension config', + }), + multi: true, + }, + addTooltip: { + types: ['boolean'], + help: i18n.translate('visTypePie.function.args.addTooltipHelpText', { + defaultMessage: 'Show tooltip on slice hover', + }), + default: true, + }, + addLegend: { + types: ['boolean'], + help: i18n.translate('visTypePie.function.args.addLegendHelpText', { + defaultMessage: 'Show legend chart legend', + }), + }, + legendPosition: { types: ['string'], - default: '"{}"', - help: 'vislib pie vis config', + help: i18n.translate('visTypePie.function.args.legendPositionHelpText', { + defaultMessage: 'Position the legend on top, bottom, left, right of the chart', + }), + }, + nestedLegend: { + types: ['boolean'], + help: i18n.translate('visTypePie.function.args.nestedLegendHelpText', { + defaultMessage: 'Show a more detailed legend', + }), + default: false, + }, + distinctColors: { + types: ['boolean'], + help: i18n.translate('visTypePie.function.args.distinctColorsHelpText', { + defaultMessage: + 'Maps different color per slice. Slices with the same value have the same color', + }), + default: false, + }, + isDonut: { + types: ['boolean'], + help: i18n.translate('visTypePie.function.args.isDonutHelpText', { + defaultMessage: 'Displays the pie chart as donut', + }), + default: false, + }, + palette: { + types: ['string'], + help: i18n.translate('visTypePie.function.args.paletteHelpText', { + defaultMessage: 'Defines the chart palette name', + }), + default: 'default', + }, + labels: { + types: ['pie_labels'], + help: i18n.translate('visTypePie.function.args.labelsHelpText', { + defaultMessage: 'Pie labels config', + }), }, }, fn(context, args, handlers) { - const visConfig = JSON.parse(args.visConfig) as PieVisParams; + const visConfig = { + ...args, + palette: { + type: 'palette', + name: args.palette, + }, + dimensions: { + metric: args.metric, + buckets: args.buckets, + splitColumn: args.splitColumn, + splitRow: args.splitRow, + }, + } as PieVisParams; if (handlers?.inspectorAdapters?.tables) { handlers.inspectorAdapters.tables.logDatatable('default', context); diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index 54c71e49f1adeb..807520f51080cc 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -6,31 +6,60 @@ * Side Public License, v 1. */ -import { getVisSchemas, VisToExpressionAst } from '../../visualizations/public'; +import { getVisSchemas, VisToExpressionAst, SchemaConfig } from '../../visualizations/public'; import { buildExpression, buildExpressionFunction } from '../../expressions/public'; - -import { PieVisParams } from './types'; +import { PieVisParams, LabelsParams } from './types'; import { vislibPieName, VisTypePieExpressionFunctionDefinition } from './pie_fn'; import { getEsaggsFn } from './to_ast_esaggs'; +const prepareDimension = (params: SchemaConfig) => { + const visdimension = buildExpressionFunction('visdimension', { accessor: params.accessor }); + + if (params.format) { + visdimension.addArgument('format', params.format.id); + visdimension.addArgument('formatParams', JSON.stringify(params.format.params)); + } + + return buildExpression([visdimension]); +}; + +const prepareLabels = (params: LabelsParams) => { + const pieLabels = buildExpressionFunction('pielabels', { + show: params.show, + last_level: params.last_level, + values: params.values, + truncate: params.truncate, + }); + if (params.position) { + pieLabels.addArgument('position', params.position); + } + if (params.valuesFormat) { + pieLabels.addArgument('valuesFormat', params.valuesFormat); + } + return buildExpression([pieLabels]); +}; + export const toExpressionAst: VisToExpressionAst = async (vis, params) => { const schemas = getVisSchemas(vis, params); - const visConfig = { - ...vis.params, - dimensions: { - metric: schemas.metric[0], - buckets: schemas.segment, - splitRow: schemas.split_row, - splitColumn: schemas.split_column, - }, + const args = { + // explicitly pass each param to prevent extra values trapping + addTooltip: vis.params.addTooltip, + addLegend: vis.params.addLegend, + legendPosition: vis.params.legendPosition, + nestedLegend: vis.params?.nestedLegend, + distinctColors: vis.params?.distinctColors, + isDonut: vis.params.isDonut, + palette: vis.params?.palette?.name, + labels: prepareLabels(vis.params.labels), + metric: schemas.metric.map(prepareDimension), + buckets: schemas.segment?.map(prepareDimension), + splitColumn: schemas.split_column?.map(prepareDimension), + splitRow: schemas.split_row?.map(prepareDimension), }; - const configStr = JSON.stringify(visConfig).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); const visTypePie = buildExpressionFunction( vislibPieName, - { - visConfig: configStr, - } + args ); const ast = buildExpression([getEsaggsFn(vis), visTypePie]); diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index bf4f3789fffba8..2d287ba6b7db04 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -9,6 +9,10 @@ import { Position } from '@elastic/charts'; import { UiCounterMetricType } from '@kbn/analytics'; import { DatatableColumn, SerializedFieldFormat } from '../../../expressions/public'; +import { + ExpressionValueVisDimension, + ExpressionValuePieLabels, +} from '../../../visualizations/public'; import { PaletteOutput, ChartsPluginSetup } from '../../../charts/public'; export interface Dimension { @@ -26,24 +30,37 @@ export interface Dimensions { splitColumn?: Dimension[]; } -export interface PieVisParams { - type: 'pie'; +interface PieCommonParams { addTooltip: boolean; addLegend: boolean; legendPosition: Position; nestedLegend: boolean; distinctColors: boolean; - dimensions: Dimensions; isDonut: boolean; +} + +export interface LabelsParams { + show: boolean; + last_level: boolean; + position: LabelPositions; + values: boolean; + truncate: number | null; + valuesFormat: ValueFormats; +} + +export interface PieVisParams extends PieCommonParams { + dimensions: Dimensions; + labels: LabelsParams; palette: PaletteOutput; - labels: { - show: boolean; - last_level: boolean; - position: LabelPositions; - values: boolean; - truncate: number | null; - valuesFormat: ValueFormats; - }; +} + +export interface PieVisConfig extends PieCommonParams { + buckets?: ExpressionValueVisDimension[]; + metric: ExpressionValueVisDimension; + splitColumn?: ExpressionValueVisDimension[]; + splitRow?: ExpressionValueVisDimension[]; + labels: ExpressionValuePieLabels; + palette: string; } export interface BucketColumns extends DatatableColumn { diff --git a/src/plugins/visualizations/public/expression_functions/pie_labels.ts b/src/plugins/visualizations/public/expression_functions/pie_labels.ts new file mode 100644 index 00000000000000..eed7c84fd2608e --- /dev/null +++ b/src/plugins/visualizations/public/expression_functions/pie_labels.ts @@ -0,0 +1,103 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { + ExpressionFunctionDefinition, + Datatable, + ExpressionValueBoxed, +} from '../../../expressions/public'; + +interface Arguments { + show: boolean; + position: string; + values: boolean; + truncate: number | null; + valuesFormat: string; + last_level: boolean; +} + +export type ExpressionValuePieLabels = ExpressionValueBoxed< + 'pie_labels', + { + show: boolean; + position: string; + values: boolean; + truncate: number | null; + valuesFormat: string; + last_level: boolean; + } +>; + +export const pieLabels = (): ExpressionFunctionDefinition< + 'pielabels', + Datatable | null, + Arguments, + ExpressionValuePieLabels +> => ({ + name: 'pielabels', + help: i18n.translate('visualizations.function.pieLabels.help', { + defaultMessage: 'Generates the pie labels object', + }), + type: 'pie_labels', + args: { + show: { + types: ['boolean'], + help: i18n.translate('visualizations.function.pieLabels.show.help', { + defaultMessage: 'Displays the pie labels', + }), + required: true, + }, + position: { + types: ['string'], + default: 'default', + help: i18n.translate('visualizations.function.pieLabels.position.help', { + defaultMessage: 'Defines the label position', + }), + }, + values: { + types: ['boolean'], + help: i18n.translate('visualizations.function.pieLabels.values.help', { + defaultMessage: 'Displays the values inside the slices', + }), + default: true, + }, + last_level: { + types: ['boolean'], + help: i18n.translate('visualizations.function.pieLabels.values.help', { + defaultMessage: 'Show top level labels only', + }), + default: true, + }, + truncate: { + types: ['number', 'null'], + help: i18n.translate('visualizations.function.pieLabels.truncate.help', { + defaultMessage: 'Defines the number of characters that the slice value will display', + }), + default: null, + }, + valuesFormat: { + types: ['string'], + default: 'percent', + help: i18n.translate('visualizations.function.pieLabels.valuesFormat.help', { + defaultMessage: 'Defines the format of the values', + }), + }, + }, + fn: (context, args) => { + return { + type: 'pie_labels', + show: args.show, + position: args.position, + values: args.values, + truncate: args.truncate, + valuesFormat: args.valuesFormat, + last_level: args.last_level, + }; + }, +}); diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index dbcbb864d2316b..5baf0f8dc90b42 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -44,3 +44,4 @@ export { VisualizationListItem, VisualizationStage } from './vis_types/vis_type_ export { VISUALIZE_ENABLE_LABS_SETTING } from '../common/constants'; export { SavedVisState, VisParams } from '../common'; export { ExpressionValueVisDimension } from './expression_functions/vis_dimension'; +export { ExpressionValuePieLabels } from './expression_functions/pie_labels'; diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index 081f5d65103c20..1e788b18876283 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -46,6 +46,7 @@ import { ExpressionsSetup, ExpressionsStart } from '../../expressions/public'; import { EmbeddableSetup, EmbeddableStart } from '../../embeddable/public'; import { range as rangeExpressionFunction } from './expression_functions/range'; import { visDimension as visDimensionExpressionFunction } from './expression_functions/vis_dimension'; +import { pieLabels as pieLabelsExpressionFunction } from './expression_functions/pie_labels'; import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../plugins/data/public'; import { Setup as InspectorSetup, @@ -133,6 +134,7 @@ export class VisualizationsPlugin expressions.registerFunction(rangeExpressionFunction); expressions.registerFunction(visDimensionExpressionFunction); + expressions.registerFunction(pieLabelsExpressionFunction); const embeddableFactory = new VisualizeEmbeddableFactory({ start }); embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); From 848fd76d52d94090f5231d6796e5ca76e686cf14 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 26 Apr 2021 15:55:40 +0300 Subject: [PATCH 081/111] Fix i18n failure --- .../visualizations/public/expression_functions/pie_labels.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/visualizations/public/expression_functions/pie_labels.ts b/src/plugins/visualizations/public/expression_functions/pie_labels.ts index eed7c84fd2608e..322b6fbe983621 100644 --- a/src/plugins/visualizations/public/expression_functions/pie_labels.ts +++ b/src/plugins/visualizations/public/expression_functions/pie_labels.ts @@ -69,7 +69,7 @@ export const pieLabels = (): ExpressionFunctionDefinition< }, last_level: { types: ['boolean'], - help: i18n.translate('visualizations.function.pieLabels.values.help', { + help: i18n.translate('visualizations.function.pieLabels.lastLevel.help', { defaultMessage: 'Show top level labels only', }), default: true, From 7809b38d1e5e6ae5e45b9c70802fc3a7da188533 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 27 Apr 2021 12:08:17 +0300 Subject: [PATCH 082/111] Add top level setting --- .../public/editor/components/pie.tsx | 26 +++++++++++-------- .../vis_type_pie/public/pie_component.tsx | 8 ++++-- .../vis_type_pie/public/utils/get_config.ts | 9 +++++++ .../vis_type_pie/public/vis_type/pie.ts | 2 +- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 860026450cab72..7b7e6468787ca5 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -170,21 +170,25 @@ const PieOptions = (props: PieOptionsProps) => { data-test-subj="visTypePieLabelPositionSelect" /> )} - {!props.showElasticChartsOptions && ( - - )} + { valueAccessor={(d: Datum) => getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} valueGetter={ - !visParams.labels.show || visParams.labels.valuesFormat === ValueFormats.VALUE + !visParams.labels.show || + visParams.labels.valuesFormat === ValueFormats.VALUE || + !visParams.labels.values ? undefined : 'percent' } valueFormatter={(d: number) => - !visParams.labels.show ? '' : metricFieldFormatter.convert(d) + !visParams.labels.show || !visParams.labels.values + ? '' + : metricFieldFormatter.convert(d) } layers={layers} config={config} diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 55978519ec08eb..8dd5b5debf16c8 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -36,6 +36,15 @@ export const getConfig = ( config.linkLabel = { maxCount: 0, maximumSection: Number.POSITIVE_INFINITY }; } + if (visParams.labels.last_level && visParams.labels.show) { + config.linkLabel = { + maxCount: Number.POSITIVE_INFINITY, + maximumSection: Number.POSITIVE_INFINITY, + // valueFormatter: !visParams.labels.values ? () => '' : undefined, + valueFormatter: () => '', + }; + } + // On small multiples we want the labels to only appear inside const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); if (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) { diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index f7762c05e4672e..de6c7fd7ff6d73 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -42,7 +42,7 @@ export const getPieVisTypeDefinition = ({ }, labels: { show: true, - last_level: true, + last_level: !showElasticChartsOptions, values: true, valuesFormat: ValueFormats.PERCENT, truncate: 100, From d3040303158a95c84c1dbabdc56edc914858ffe9 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 27 Apr 2021 12:16:26 +0300 Subject: [PATCH 083/111] Minor fix --- test/functional/apps/visualize/_pie_chart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/apps/visualize/_pie_chart.ts b/test/functional/apps/visualize/_pie_chart.ts index 11f886c052899f..6b26f165d7a3bc 100644 --- a/test/functional/apps/visualize/_pie_chart.ts +++ b/test/functional/apps/visualize/_pie_chart.ts @@ -403,7 +403,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await inspector.close(); }); - it('should correctly filter on legend miaou', async () => { + it('should correctly filter on legend', async () => { const expectedTableData = [ '0', 'CN', From 5cf97e77ac6239dff196a462a7b2832456d5daf7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 27 Apr 2021 13:34:47 +0300 Subject: [PATCH 084/111] Fix jest tests --- .../vis_type_pie/public/editor/components/pie.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index 3e3550f3dd283b..b48e6dcadd9293 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -86,10 +86,10 @@ describe('PalettePicker', function () { }); }); - it('not renders the top level switch for the elastic charts implementation', async () => { + it('renders the top level switch for the elastic charts implementation', async () => { component = mountWithIntl(); await act(async () => { - expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(0); + expect(findTestSubject(component, 'visTypePieTopLevelSwitch').length).toBe(1); }); }); From a237705fdbff250530add2a1b5aab7eb4e54a956 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 28 Apr 2021 10:17:45 +0300 Subject: [PATCH 085/111] Address PR comments --- src/plugins/vis_type_pie/common/index.ts | 9 +++ .../public/__snapshots__/pie_fn.test.ts.snap | 1 + .../public/editor/components/pie.test.tsx | 8 ++ .../public/editor/components/pie.tsx | 80 +++++++++++++++---- src/plugins/vis_type_pie/public/mocks.ts | 1 + .../vis_type_pie/public/pie_component.tsx | 3 +- .../vis_type_pie/public/pie_fn.test.ts | 1 + src/plugins/vis_type_pie/public/to_ast.ts | 3 + .../vis_type_pie/public/types/types.ts | 1 + .../public/utils/get_columns.test.ts | 2 + .../vis_type_pie/public/vis_type/pie.ts | 2 + .../public/expression_functions/pie_labels.ts | 10 +++ 12 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 src/plugins/vis_type_pie/common/index.ts diff --git a/src/plugins/vis_type_pie/common/index.ts b/src/plugins/vis_type_pie/common/index.ts new file mode 100644 index 00000000000000..1aa1680530b324 --- /dev/null +++ b/src/plugins/vis_type_pie/common/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export const DEFAULT_PERCENT_DECIMALS = 2; diff --git a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap index bedac0b062b6b9..dc83d9fdf48ac5 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/pie_fn.test.ts.snap @@ -29,6 +29,7 @@ Object { "distinctColors": false, "isDonut": true, "labels": Object { + "percentDecimals": 2, "position": "default", "show": false, "truncate": 100, diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx index b48e6dcadd9293..524986524fd7e5 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.test.tsx @@ -55,6 +55,7 @@ describe('PalettePicker', function () { show: true, }, }, + setValue: jest.fn(), } as unknown) as PieOptionsProps; }); @@ -113,4 +114,11 @@ describe('PalettePicker', function () { expect(findTestSubject(component, 'visTypePieValueFormatsSelect').length).toBe(0); }); }); + + it('renders the percent slider for the elastic charts implementation', async () => { + component = mountWithIntl(); + await act(async () => { + expect(findTestSubject(component, 'visTypePieValueDecimals').length).toBe(1); + }); + }); }); diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 7b7e6468787ca5..15f56589ee6ed7 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -8,7 +8,7 @@ import React, { useState, useEffect } from 'react'; import { METRIC_TYPE } from '@kbn/analytics'; -import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; +import { EuiPanel, EuiTitle, EuiSpacer, EuiRange, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -21,12 +21,47 @@ import { import { VisEditorOptionsProps } from '../../../../visualizations/public'; import { TruncateLabelsOption } from './truncate_labels'; import { PaletteRegistry } from '../../../../charts/public'; +import { DEFAULT_PERCENT_DECIMALS } from '../../../common'; import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../../types'; import { getLabelPositions, getValuesFormats } from '../collections'; import { getLegendPositions } from '../positions'; export interface PieOptionsProps extends VisEditorOptionsProps, PieTypeProps {} +function DecimalSlider({ + paramName, + value, + setValue, + disabled, +}: { + value: number; + paramName: ParamName; + setValue: (paramName: ParamName, value: number) => void; + disabled: boolean; +}) { + return ( + + { + setValue(paramName, Number(e.currentTarget.value)); + }} + /> + + ); +} + const PieOptions = (props: PieOptionsProps) => { const { stateParams, setValue, aggs } = props; const setLabels = ( @@ -40,6 +75,7 @@ const PieOptions = (props: PieOptionsProps) => { return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); const hasSplitChart = aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled); + const segments = aggs?.aggs?.filter((agg) => agg.schema === 'segment' && agg.enabled); useEffect(() => { setLegendVisibility(legendUiStateValue); @@ -82,6 +118,7 @@ const PieOptions = (props: PieOptionsProps) => { })} paramName="distinctColors" value={stateParams.distinctColors} + disabled={segments?.length <= 1 && !Boolean(hasSplitChart)} setValue={setValue} data-test-subj="visTypePiedistinctColorsSwitch" /> @@ -103,6 +140,7 @@ const PieOptions = (props: PieOptionsProps) => { })} paramName="nestedLegend" value={stateParams.nestedLegend} + disabled={!stateParams.addLegend} setValue={(paramName, value) => { if (props.trackUiMetric) { props.trackUiMetric(METRIC_TYPE.CLICK, 'nested_legend_switched'); @@ -194,22 +232,32 @@ const PieOptions = (props: PieOptionsProps) => { setValue={setLabels} /> {props.showElasticChartsOptions && ( - { - if (props.trackUiMetric) { - props.trackUiMetric(METRIC_TYPE.CLICK, 'values_format_selected'); + <> + { + if (props.trackUiMetric) { + props.trackUiMetric(METRIC_TYPE.CLICK, 'values_format_selected'); + } + setLabels(paramName, value); + }} + data-test-subj="visTypePieValueFormatsSelect" + /> + + /> + )} diff --git a/src/plugins/vis_type_pie/public/mocks.ts b/src/plugins/vis_type_pie/public/mocks.ts index 7315543cc2888d..53579422e44eba 100644 --- a/src/plugins/vis_type_pie/public/mocks.ts +++ b/src/plugins/vis_type_pie/public/mocks.ts @@ -275,6 +275,7 @@ export const createMockPieParams = (): PieVisParams => { truncate: 100, values: true, valuesFormat: ValueFormats.PERCENT, + percentDecimals: 2, }, legendPosition: 'right', nestedLegend: false, diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 01d75ccbcec6f8..0fdf6f82b1c2e1 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -29,6 +29,7 @@ import { import { DataPublicPluginStart, FieldFormat } from '../../data/public'; import type { PersistedState } from '../../visualizations/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; +import { DEFAULT_PERCENT_DECIMALS } from '../common'; import { PieVisParams, BucketColumns, ValueFormats } from './types'; import { getColorPicker, @@ -187,7 +188,7 @@ const PieComponent = (props: PieComponentProps) => { const percentFormatter = services.fieldFormats.deserialize({ id: 'percent', params: { - pattern: '0.[00]%', + pattern: `0,0.[${'0'.repeat(visParams.labels.percentDecimals ?? DEFAULT_PERCENT_DECIMALS)}]%`, }, }); diff --git a/src/plugins/vis_type_pie/public/pie_fn.test.ts b/src/plugins/vis_type_pie/public/pie_fn.test.ts index 45a43e44f6ccc5..d387d4035e8ab5 100644 --- a/src/plugins/vis_type_pie/public/pie_fn.test.ts +++ b/src/plugins/vis_type_pie/public/pie_fn.test.ts @@ -29,6 +29,7 @@ describe('interpreter/functions#pie', () => { values: true, position: 'default', valuesFormat: 'percent', + percentDecimals: 2, truncate: 100, }, metric: { diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index 807520f51080cc..cc1c99e6a8a44d 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -36,6 +36,9 @@ const prepareLabels = (params: LabelsParams) => { if (params.valuesFormat) { pieLabels.addArgument('valuesFormat', params.valuesFormat); } + if (params.percentDecimals) { + pieLabels.addArgument('percentDecimals', params.percentDecimals); + } return buildExpression([pieLabels]); }; diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 2d287ba6b7db04..1b7594ff545841 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -46,6 +46,7 @@ export interface LabelsParams { values: boolean; truncate: number | null; valuesFormat: ValueFormats; + percentDecimals: number; } export interface PieVisParams extends PieCommonParams { diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index ec8db536d0c59f..8f88d432d9c148 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -140,6 +140,7 @@ describe('getColumns', () => { truncate: 100, values: true, valuesFormat: 'percent', + percentDecimals: 2, }, legendPosition: 'right', nestedLegend: false, @@ -164,6 +165,7 @@ describe('getColumns', () => { truncate: 100, values: true, valuesFormat: 'percent', + percentDecimals: 2, }, legendPosition: 'right', nestedLegend: false, diff --git a/src/plugins/vis_type_pie/public/vis_type/pie.ts b/src/plugins/vis_type_pie/public/vis_type/pie.ts index de6c7fd7ff6d73..9d1556ac33ad7e 100644 --- a/src/plugins/vis_type_pie/public/vis_type/pie.ts +++ b/src/plugins/vis_type_pie/public/vis_type/pie.ts @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; import { AggGroupNames } from '../../../data/public'; import { VIS_EVENT_TO_TRIGGER, VisTypeDefinition } from '../../../visualizations/public'; +import { DEFAULT_PERCENT_DECIMALS } from '../../common'; import { PieVisParams, LabelPositions, ValueFormats, PieTypeProps } from '../types'; import { toExpressionAst } from '../to_ast'; import { getPieOptions } from '../editor/components'; @@ -45,6 +46,7 @@ export const getPieVisTypeDefinition = ({ last_level: !showElasticChartsOptions, values: true, valuesFormat: ValueFormats.PERCENT, + percentDecimals: DEFAULT_PERCENT_DECIMALS, truncate: 100, position: LabelPositions.DEFAULT, }, diff --git a/src/plugins/visualizations/public/expression_functions/pie_labels.ts b/src/plugins/visualizations/public/expression_functions/pie_labels.ts index 322b6fbe983621..2005dc61f7cb06 100644 --- a/src/plugins/visualizations/public/expression_functions/pie_labels.ts +++ b/src/plugins/visualizations/public/expression_functions/pie_labels.ts @@ -20,6 +20,7 @@ interface Arguments { truncate: number | null; valuesFormat: string; last_level: boolean; + percentDecimals: number; } export type ExpressionValuePieLabels = ExpressionValueBoxed< @@ -31,6 +32,7 @@ export type ExpressionValuePieLabels = ExpressionValueBoxed< truncate: number | null; valuesFormat: string; last_level: boolean; + percentDecimals: number; } >; @@ -67,6 +69,13 @@ export const pieLabels = (): ExpressionFunctionDefinition< }), default: true, }, + percentDecimals: { + types: ['number'], + help: i18n.translate('visualizations.function.pieLabels.percentDecimals.help', { + defaultMessage: 'Defines the number of decimals that will appear on the values as percent', + }), + default: 2, + }, last_level: { types: ['boolean'], help: i18n.translate('visualizations.function.pieLabels.lastLevel.help', { @@ -94,6 +103,7 @@ export const pieLabels = (): ExpressionFunctionDefinition< type: 'pie_labels', show: args.show, position: args.position, + percentDecimals: args.percentDecimals, values: args.values, truncate: args.truncate, valuesFormat: args.valuesFormat, From 146731abd5d146f7d06f790bc92ed923f18e079f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 28 Apr 2021 10:32:24 +0300 Subject: [PATCH 086/111] Fix i18n error --- src/plugins/vis_type_pie/public/editor/components/pie.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 15f56589ee6ed7..2ea3110146b9e7 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -42,7 +42,7 @@ function DecimalSlider({ return ( Date: Wed, 28 Apr 2021 12:50:16 +0300 Subject: [PATCH 087/111] fix functional test --- test/functional/apps/visualize/_pie_chart.ts | 1 + test/functional/page_objects/visualize_editor_page.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/test/functional/apps/visualize/_pie_chart.ts b/test/functional/apps/visualize/_pie_chart.ts index 6b26f165d7a3bc..abbab0abe2b76a 100644 --- a/test/functional/apps/visualize/_pie_chart.ts +++ b/test/functional/apps/visualize/_pie_chart.ts @@ -428,6 +428,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ].sort(); if (await PageObjects.visChart.isNewLibraryChart('visTypePieChart')) { await PageObjects.visEditor.clickOptionsTab(); + await PageObjects.visEditor.togglePieLegend(); await PageObjects.visEditor.togglePieNestedLegend(); await PageObjects.visEditor.clickDataTab(); await PageObjects.visEditor.clickGo(); diff --git a/test/functional/page_objects/visualize_editor_page.ts b/test/functional/page_objects/visualize_editor_page.ts index c533e25b38da0f..47cbc8c5e3ea3f 100644 --- a/test/functional/page_objects/visualize_editor_page.ts +++ b/test/functional/page_objects/visualize_editor_page.ts @@ -327,6 +327,10 @@ export function VisualizeEditorPageProvider({ getService, getPageObjects }: FtrP await testSubjects.click('visualizeEditorAutoButton'); } + public async togglePieLegend() { + await testSubjects.click('visTypePieAddLegendSwitch'); + } + public async togglePieNestedLegend() { await testSubjects.click('visTypePieNestedLegendSwitch'); } From 54e31813bce0a86f1d359d1dc6151ccec5be7d3f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 29 Apr 2021 10:29:45 +0300 Subject: [PATCH 088/111] Add an icon tip on the distinct colors per slice switch --- .../public/editor/components/pie.tsx | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 2ea3110146b9e7..b0ac02cd1ce2f9 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -8,7 +8,16 @@ import React, { useState, useEffect } from 'react'; import { METRIC_TYPE } from '@kbn/analytics'; -import { EuiPanel, EuiTitle, EuiSpacer, EuiRange, EuiFormRow } from '@elastic/eui'; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiRange, + EuiFormRow, + EuiIconTip, + EuiFlexItem, + EuiFlexGroup, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -112,16 +121,30 @@ const PieOptions = (props: PieOptionsProps) => { {props.showElasticChartsOptions && ( <> - + + + + + + + + + + Date: Thu, 29 Apr 2021 15:57:59 +0300 Subject: [PATCH 089/111] Fix some of the PR comments --- src/plugins/vis_type_pie/public/chart.scss | 4 -- .../public/editor/components/pie.tsx | 11 ++-- .../vis_type_pie/public/pie_component.tsx | 9 ++- src/plugins/vis_type_pie/public/plugin.ts | 2 +- .../public/utils/filter_helpers.ts | 12 ++-- .../public/utils/get_color_picker.tsx | 2 +- .../vis_type_pie/public/utils/get_config.ts | 2 - .../public/utils/get_distinct_series.ts | 2 +- .../vis_type_pie/public/utils/get_layers.ts | 63 +++++++++---------- ...sor.ts => get_split_dimension_accessor.ts} | 9 +-- .../vis_type_pie/public/utils/index.ts | 2 +- 11 files changed, 58 insertions(+), 60 deletions(-) rename src/plugins/vis_type_pie/public/utils/{get_complex_accessor.ts => get_split_dimension_accessor.ts} (79%) diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index 0acfefda84fc97..5febeea3019cb4 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -13,7 +13,3 @@ bottom: 0; left: 0; } - -.pieChart__container .echLegendItem { - width: initial; -} diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index b0ac02cd1ce2f9..895a70b62b6449 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -83,8 +83,9 @@ const PieOptions = (props: PieOptionsProps) => { const bwcLegendStateDefault = stateParams.addLegend == null ? false : stateParams.addLegend; return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); - const hasSplitChart = aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled); - const segments = aggs?.aggs?.filter((agg) => agg.schema === 'segment' && agg.enabled); + const hasSplitChart = + Boolean(aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled)) ?? false; + const segments = aggs?.aggs?.filter((agg) => agg.schema === 'segment' && agg.enabled) ?? []; useEffect(() => { setLegendVisibility(legendUiStateValue); @@ -130,7 +131,7 @@ const PieOptions = (props: PieOptionsProps) => { })} paramName="distinctColors" value={stateParams.distinctColors} - disabled={segments?.length <= 1 && !Boolean(hasSplitChart)} + disabled={segments?.length <= 1 && !hasSplitChart} setValue={setValue} data-test-subj="visTypePiedistinctColorsSwitch" /> @@ -214,11 +215,11 @@ const PieOptions = (props: PieOptionsProps) => { label={i18n.translate('visTypePie.editors.pie.labelPositionLabel', { defaultMessage: 'Label position', })} - disabled={!stateParams.labels.show || Boolean(hasSplitChart)} + disabled={!stateParams.labels.show || hasSplitChart} options={getLabelPositions} paramName="position" value={ - Boolean(hasSplitChart) + hasSplitChart ? LabelPositions.INSIDE : stateParams.labels.position || LabelPositions.DEFAULT } diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 0fdf6f82b1c2e1..e6edefef3ccd58 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -40,7 +40,7 @@ import { getFilterEventData, getConfig, getColumns, - getComplexAccessor, + getSplitDimensionAccessor, } from './utils'; import { ChartSplit, SMALL_MULTIPLES_ID } from './components/chart_split'; @@ -249,13 +249,16 @@ const PieComponent = (props: PieComponentProps) => { ); const splitChartColumnAccessor = visParams.dimensions.splitColumn - ? getComplexAccessor( + ? getSplitDimensionAccessor( services.fieldFormats, visData.columns )(visParams.dimensions.splitColumn[0]) : undefined; const splitChartRowAccessor = visParams.dimensions.splitRow - ? getComplexAccessor(services.fieldFormats, visData.columns)(visParams.dimensions.splitRow[0]) + ? getSplitDimensionAccessor( + services.fieldFormats, + visData.columns + )(visParams.dimensions.splitRow[0]) : undefined; const splitChartDimension = visParams.dimensions.splitColumn diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 3a34e9308f4de9..43239a3da29881 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -52,7 +52,7 @@ export class VisTypePiePlugin { }; const trackUiMetric = usageCollection?.reportUiCounter.bind(usageCollection, 'vis_type_pie'); - [createPieVisFn].forEach(expressions.registerFunction); + expressions.registerFunction(createPieVisFn); expressions.registerRenderer( getPieVisRenderer({ theme: charts.theme, palettes: charts.palettes, getStartDeps }) ); diff --git a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts index 77d2fedf71b6d0..251ff8acc698e9 100644 --- a/src/plugins/vis_type_pie/public/utils/filter_helpers.ts +++ b/src/plugins/vis_type_pie/public/utils/filter_helpers.ts @@ -36,13 +36,13 @@ export const getFilterClickData = ( clickedLayers.every((layer, index) => { const columnId = bucketColumns[index].id; if (!columnId) return; - let condition = row[columnId] === layer.groupByRollup; - if (splitChartDimension) { - const value = - splitChartFormatter?.convert(row[splitChartDimension.id]) || row[splitChartDimension.id]; - condition = condition && value === layer.smAccessorValue; + const isCurrentLayer = row[columnId] === layer.groupByRollup; + if (!splitChartDimension) { + return isCurrentLayer; } - return condition; + const value = + splitChartFormatter?.convert(row[splitChartDimension.id]) || row[splitChartDimension.id]; + return isCurrentLayer && value === layer.smAccessorValue; }) ); diff --git a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx index c649bc578170cc..436ce81d3ce3c5 100644 --- a/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_color_picker.tsx @@ -64,7 +64,7 @@ export const getColorPicker = ( seriesIdentifiers: [seriesIdentifier], }) => { const seriesName = seriesIdentifier.key; - const overwriteColors: Record = uiState?.get('vis.colors', {}); + const overwriteColors: Record = uiState?.get('vis.colors', {}) ?? {}; const colorIsOverwritten = Object.keys(overwriteColors).includes(seriesName.toString()); let keyDownEventOn = false; const handleChange = (newColor: string | null) => { diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 8dd5b5debf16c8..e14ea1215a1247 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -40,8 +40,6 @@ export const getConfig = ( config.linkLabel = { maxCount: Number.POSITIVE_INFINITY, maximumSection: Number.POSITIVE_INFINITY, - // valueFormatter: !visParams.labels.values ? () => '' : undefined, - valueFormatter: () => '', }; } diff --git a/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts b/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts index 6a531904e6af49..ba5042dfc210c5 100644 --- a/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts +++ b/src/plugins/vis_type_pie/public/utils/get_distinct_series.ts @@ -13,8 +13,8 @@ export const getDistinctSeries = (rows: DatatableRow[], buckets: Array { + if (!id) return; rows.forEach((row) => { - if (!id) return; const name = row[id]; if (!allSeries.includes(name)) { allSeries.push(name); diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 8fc3de999b072d..b89019c5fd09f2 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -54,41 +54,40 @@ export const computeColor = ( syncColors, } ); - } else { - const seriesLayers: SeriesLayer[] = []; - let tempParent: typeof d | typeof d['parent'] = d; - while (tempParent.parent && tempParent.depth > 0) { - const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); - const isSplitParentLayer = isSplitChart && parentSeries.includes(seriesName); - seriesLayers.unshift({ - name: seriesName, - rankAtDepth: isSplitParentLayer - ? parentSeries.findIndex((name) => name === seriesName) - : tempParent.sortIndex, - totalSeriesAtDepth: isSplitParentLayer - ? parentSeries.length - : tempParent.parent.children.length, - }); - tempParent = tempParent.parent; - } - - let overwriteColor; - seriesLayers.forEach((layer) => { - if (Object.keys(overwriteColors).includes(layer.name)) { - overwriteColor = overwriteColors[layer.name]; - } + } + const seriesLayers: SeriesLayer[] = []; + let tempParent: typeof d | typeof d['parent'] = d; + while (tempParent.parent && tempParent.depth > 0) { + const seriesName = String(tempParent.parent.children[tempParent.sortIndex][0]); + const isSplitParentLayer = isSplitChart && parentSeries.includes(seriesName); + seriesLayers.unshift({ + name: seriesName, + rankAtDepth: isSplitParentLayer + ? parentSeries.findIndex((name) => name === seriesName) + : tempParent.sortIndex, + totalSeriesAtDepth: isSplitParentLayer + ? parentSeries.length + : tempParent.parent.children.length, }); + tempParent = tempParent.parent; + } - if (overwriteColor) { - return lightenColor(overwriteColor, seriesLayers.length, columns.length); + let overwriteColor; + seriesLayers.forEach((layer) => { + if (Object.keys(overwriteColors).includes(layer.name)) { + overwriteColor = overwriteColors[layer.name]; } - return palettes?.get(visParams.palette.name).getColor(seriesLayers, { - behindText: visParams.labels.show, - maxDepth: columns.length, - totalSeries: rows.length, - syncColors, - }); + }); + + if (overwriteColor) { + return lightenColor(overwriteColor, seriesLayers.length, columns.length); } + return palettes?.get(visParams.palette.name).getColor(seriesLayers, { + behindText: visParams.labels.show, + maxDepth: columns.length, + totalSeries: rows.length, + syncColors, + }); }; export const getLayers = ( @@ -129,7 +128,7 @@ export const getLayers = ( return String(d); }, sortPredicate: ([name1, node1]: ArrayEntry, [name2, node2]: ArrayEntry) => { - const params = col?.meta?.sourceParams?.params as SplitDimensionParams; + const params = col?.meta?.sourceParams?.params as SplitDimensionParams | undefined; const sort: string | undefined = params?.orderBy; // metric sorting if (sort !== '_key') { diff --git a/src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts b/src/plugins/vis_type_pie/public/utils/get_split_dimension_accessor.ts similarity index 79% rename from src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts rename to src/plugins/vis_type_pie/public/utils/get_split_dimension_accessor.ts index eec4f9fc09967d..e1029b11a7b758 100644 --- a/src/plugins/vis_type_pie/public/utils/get_complex_accessor.ts +++ b/src/plugins/vis_type_pie/public/utils/get_split_dimension_accessor.ts @@ -5,14 +5,15 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { AccessorFn, Accessor } from '@elastic/charts'; +import { AccessorFn } from '@elastic/charts'; import { FieldFormatsStart } from '../../../data/public'; import { DatatableColumn } from '../../../expressions/public'; import { Dimension } from '../types'; -export const getComplexAccessor = (fieldFormats: FieldFormatsStart, columns: DatatableColumn[]) => ( - splitDimension: Dimension -): Accessor | AccessorFn | undefined => { +export const getSplitDimensionAccessor = ( + fieldFormats: FieldFormatsStart, + columns: DatatableColumn[] +) => (splitDimension: Dimension): AccessorFn => { const formatter = fieldFormats.deserialize(splitDimension.format); const splitChartColumn = columns[splitDimension.accessor]; const accessor = splitChartColumn.id; diff --git a/src/plugins/vis_type_pie/public/utils/index.ts b/src/plugins/vis_type_pie/public/utils/index.ts index 19a849308bb70f..0cf4292ad565a9 100644 --- a/src/plugins/vis_type_pie/public/utils/index.ts +++ b/src/plugins/vis_type_pie/public/utils/index.ts @@ -12,5 +12,5 @@ export { getLegendActions } from './get_legend_actions'; export { canFilter, getFilterClickData, getFilterEventData } from './filter_helpers'; export { getConfig } from './get_config'; export { getColumns } from './get_columns'; -export { getComplexAccessor } from './get_complex_accessor'; +export { getSplitDimensionAccessor } from './get_split_dimension_accessor'; export { getDistinctSeries } from './get_distinct_series'; From 9994cedc5d135bbc137f8458f11d661be81d43f3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 29 Apr 2021 16:58:18 +0300 Subject: [PATCH 090/111] Address more PR comments --- src/plugins/vis_type_pie/public/utils/get_layers.ts | 2 +- .../vis_type_pie/public/utils/get_legend_actions.tsx | 6 ++++-- src/plugins/vis_type_vislib/public/plugin.ts | 2 +- test/functional/page_objects/visualize_chart_page.ts | 5 +---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index b89019c5fd09f2..fcec5fe7b4d87b 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -122,7 +122,7 @@ export const getLayers = ( defaultMessage: '(empty)', }); } - if (col?.meta?.params) { + if (col.format) { return formatter.deserialize(col.format).convert(d) ?? ''; } return String(d); diff --git a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx index 50a66f7a0ec3f1..9f1d5e0db4583a 100644 --- a/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx +++ b/src/plugins/vis_type_pie/public/utils/get_legend_actions.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; @@ -31,7 +31,9 @@ export const getLegendActions = ( const [isfilterable, setIsfilterable] = useState(true); const filterData = getFilterEventData(pieSeries); - (async () => setIsfilterable(await canFilter(filterData, actions)))(); + useEffect(() => { + (async () => setIsfilterable(await canFilter(filterData, actions)))(); + }, [filterData]); if (!isfilterable || !filterData) { return null; diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts index 78107239ac0fd9..52faf8a74778c3 100644 --- a/src/plugins/vis_type_vislib/public/plugin.ts +++ b/src/plugins/vis_type_vislib/public/plugin.ts @@ -54,7 +54,7 @@ export class VisTypeVislibPlugin // Register only non-replaced vis types convertedTypeDefinitions.forEach(visualizations.createBaseVisualization); expressions.registerRenderer(getVislibVisRenderer(core, charts)); - [createVisTypeVislibVisFn()].forEach(expressions.registerFunction); + expressions.registerFunction(createVisTypeVislibVisFn()); } else { // Register all vis types visLibVisTypeDefinitions.forEach(visualizations.createBaseVisualization); diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index 74bf68be3d681b..232c09ec682e50 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -414,10 +414,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr public async openLegendOptionColors(name: string, chartSelector = xyChartSelector) { await this.waitForVisualizationRenderingStabilized(); await retry.try(async () => { - if ( - (await this.isNewLibraryChart(xyChartSelector)) || - (await this.isNewLibraryChart(pieChartSelector)) - ) { + if (await this.isNewLibraryChart(chartSelector)) { const chart = await find.byCssSelector(chartSelector); const legendItemColor = await chart.findByCssSelector( `[data-ech-series-name="${name}"] .echLegendItem__color` From 4d58be4588eb61215f13c8e6db17bc479caa9899 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 29 Apr 2021 17:01:31 +0300 Subject: [PATCH 091/111] Small fix --- src/plugins/vis_type_pie/public/editor/components/pie.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 895a70b62b6449..385bc8cfab54d1 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -83,8 +83,7 @@ const PieOptions = (props: PieOptionsProps) => { const bwcLegendStateDefault = stateParams.addLegend == null ? false : stateParams.addLegend; return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); - const hasSplitChart = - Boolean(aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled)) ?? false; + const hasSplitChart = Boolean(aggs?.aggs?.find((agg) => agg.schema === 'split' && agg.enabled)); const segments = aggs?.aggs?.filter((agg) => agg.schema === 'segment' && agg.enabled) ?? []; useEffect(() => { From fd4cc6173d43143c703ccf55087bc35605759140 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 29 Apr 2021 17:56:29 +0300 Subject: [PATCH 092/111] Functional test --- test/functional/page_objects/visualize_chart_page.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index 232c09ec682e50..7ecf800b4be7c0 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -411,10 +411,13 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr ); } - public async openLegendOptionColors(name: string, chartSelector = xyChartSelector) { + public async openLegendOptionColors(name: string, chartSelector: string) { await this.waitForVisualizationRenderingStabilized(); await retry.try(async () => { - if (await this.isNewLibraryChart(chartSelector)) { + if ( + (await this.isNewLibraryChart(xyChartSelector)) || + (await this.isNewLibraryChart(pieChartSelector)) + ) { const chart = await find.byCssSelector(chartSelector); const legendItemColor = await chart.findByCssSelector( `[data-ech-series-name="${name}"] .echLegendItem__color` From 12abdd25cbbeddc7e0621624e8f668d2f7c4496d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 5 May 2021 10:12:37 +0300 Subject: [PATCH 093/111] address some PR comments --- .../public/__snapshots__/to_ast.test.ts.snap | 121 +++++++++++++++++- .../public/editor/components/pie.tsx | 6 +- .../public/sample_vis.test.mocks.ts | 7 + .../vis_type_pie/public/to_ast.test.ts | 26 +--- src/plugins/vis_type_pie/public/to_ast.ts | 2 +- .../public/utils/get_columns.test.ts | 51 +++++++- .../vis_type_pie/public/utils/get_columns.ts | 40 +++--- .../vis_type_pie/public/utils/get_config.ts | 5 +- .../vis_type_pie/public/utils/get_layers.ts | 2 +- 9 files changed, 211 insertions(+), 49 deletions(-) diff --git a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap index c8cc6192ca1418..0f4581a4157a07 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap @@ -1,3 +1,122 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`pie vis toExpressionAst function should match basic snapshot 1`] = `undefined`; +exports[`vis type pie vis toExpressionAst function should match basic snapshot 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "aggs": Array [], + "index": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "id": Array [ + "123", + ], + }, + "function": "indexPatternLoad", + "type": "function", + }, + ], + "type": "expression", + }, + ], + "metricsAtAllLevels": Array [ + true, + ], + "partialRows": Array [ + false, + ], + }, + "function": "esaggs", + "type": "function", + }, + Object { + "arguments": Object { + "addLegend": Array [ + true, + ], + "addTooltip": Array [ + true, + ], + "buckets": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "accessor": Array [ + 1, + ], + "format": Array [ + "terms", + ], + "formatParams": Array [ + "{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}", + ], + }, + "function": "visdimension", + "type": "function", + }, + ], + "type": "expression", + }, + ], + "isDonut": Array [ + true, + ], + "labels": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "last_level": Array [ + true, + ], + "show": Array [ + true, + ], + "truncate": Array [ + 100, + ], + "values": Array [ + true, + ], + }, + "function": "pielabels", + "type": "function", + }, + ], + "type": "expression", + }, + ], + "legendPosition": Array [ + "right", + ], + "metric": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "accessor": Array [ + 0, + ], + "format": Array [ + "number", + ], + }, + "function": "visdimension", + "type": "function", + }, + ], + "type": "expression", + }, + ], + }, + "function": "pie_vis", + "type": "function", + }, + ], + "type": "expression", +} +`; diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 385bc8cfab54d1..ada2816fc5d1cb 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -126,7 +126,7 @@ const PieOptions = (props: PieOptionsProps) => { { { /> true, diff --git a/src/plugins/vis_type_pie/public/to_ast.test.ts b/src/plugins/vis_type_pie/public/to_ast.test.ts index d33a0564c013dd..019c6e21767105 100644 --- a/src/plugins/vis_type_pie/public/to_ast.test.ts +++ b/src/plugins/vis_type_pie/public/to_ast.test.ts @@ -7,29 +7,13 @@ */ import { Vis } from '../../visualizations/public'; -import { buildExpression } from '../../expressions/public'; import { PieVisParams } from './types'; import { samplePieVis } from './sample_vis.test.mocks'; import { toExpressionAst } from './to_ast'; -jest.mock('../../expressions/public', () => ({ - ...(jest.requireActual('../../expressions/public') as any), - buildExpression: jest.fn().mockImplementation(() => ({ - toAst: () => ({ - type: 'expression', - chain: [], - }), - })), -})); - -jest.mock('./to_ast_esaggs', () => ({ - getEsaggsFn: jest.fn(), -})); - -describe('pie vis toExpressionAst function', () => { +describe('vis type pie vis toExpressionAst function', () => { let vis: Vis; - const params = { timefilter: {}, timeRange: {}, @@ -40,10 +24,8 @@ describe('pie vis toExpressionAst function', () => { vis = samplePieVis as any; }); - it('should match basic snapshot', () => { - toExpressionAst(vis, params); - const [, builtExpression] = (buildExpression as jest.Mock).mock.calls[0][0]; - - expect(builtExpression).toMatchSnapshot(); + it('should match basic snapshot', async () => { + const actual = await toExpressionAst(vis, params); + expect(actual).toMatchSnapshot(); }); }); diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index cc1c99e6a8a44d..41b345d4aefd3a 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -36,7 +36,7 @@ const prepareLabels = (params: LabelsParams) => { if (params.valuesFormat) { pieLabels.addArgument('valuesFormat', params.valuesFormat); } - if (params.percentDecimals) { + if (params.percentDecimals != null) { pieLabels.addArgument('percentDecimals', params.percentDecimals); } return buildExpression([pieLabels]); diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts index 8f88d432d9c148..3170628ec2e125 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.test.ts @@ -130,7 +130,7 @@ describe('getColumns', () => { }); it('should return the first data column if no buckets specified', () => { - const visParamsNoDimensions = ({ + const visParamsOnlyMetric = ({ addLegend: true, addTooltip: true, isDonut: true, @@ -149,13 +149,43 @@ describe('getColumns', () => { type: 'palette', }, type: 'pie', + dimensions: { + metric: { + accessor: 1, + format: { + id: 'number', + }, + params: {}, + label: 'Count', + aggType: 'count', + }, + }, } as unknown) as PieVisParams; - const { metricColumn } = getColumns(visParamsNoDimensions, visData); - expect(metricColumn).toEqual(visData.columns[0]); + const { metricColumn } = getColumns(visParamsOnlyMetric, visData); + expect(metricColumn).toEqual({ + id: 'col-1-1', + meta: { + index: 'kibana_sample_data_flights', + params: { + id: 'number', + }, + source: 'esaggs', + sourceParams: { + enabled: true, + id: '1', + indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + params: {}, + schema: 'metric', + type: 'count', + }, + type: 'number', + }, + name: 'Count', + }); }); it('should return an object with the name of the metric if no buckets specified', () => { - const visParamsNoDimensions = ({ + const visParamsOnlyMetric = ({ addLegend: true, addTooltip: true, isDonut: true, @@ -174,8 +204,19 @@ describe('getColumns', () => { type: 'palette', }, type: 'pie', + dimensions: { + metric: { + accessor: 1, + format: { + id: 'number', + }, + params: {}, + label: 'Count', + aggType: 'count', + }, + }, } as unknown) as PieVisParams; - const { bucketColumns, metricColumn } = getColumns(visParamsNoDimensions, visData); + const { bucketColumns, metricColumn } = getColumns(visParamsOnlyMetric, visData); expect(bucketColumns).toEqual([{ name: metricColumn.name }]); }); }); diff --git a/src/plugins/vis_type_pie/public/utils/get_columns.ts b/src/plugins/vis_type_pie/public/utils/get_columns.ts index 393ce9d7979d38..4a32466d808da1 100644 --- a/src/plugins/vis_type_pie/public/utils/get_columns.ts +++ b/src/plugins/vis_type_pie/public/utils/get_columns.ts @@ -9,25 +9,35 @@ import { DatatableColumn, Datatable } from '../../../expressions/public'; import { BucketColumns, PieVisParams } from '../types'; -export const getColumns = (visParams: PieVisParams, visData: Datatable) => { - const bucketColumns: Array> = []; - let metricColumn: DatatableColumn; - if (visParams?.dimensions?.buckets) { - visParams.dimensions.buckets.forEach((b) => { - bucketColumns.push({ ...visData.columns[b.accessor], format: b.format }); - }); +export const getColumns = ( + visParams: PieVisParams, + visData: Datatable +): { + metricColumn: DatatableColumn; + bucketColumns: Array>; +} => { + if (visParams.dimensions.buckets && visParams.dimensions.buckets.length > 0) { + const bucketColumns: Array> = visParams.dimensions.buckets.map( + ({ accessor, format }) => ({ + ...visData.columns[accessor], + format, + }) + ); const lastBucketId = bucketColumns[bucketColumns.length - 1].id; const matchingIndex = visData.columns.findIndex((col) => col.id === lastBucketId); - metricColumn = visData.columns[matchingIndex + 1]; - } else { - const metricAccessor = visParams?.dimensions?.metric.accessor; - metricColumn = visData.columns[metricAccessor ?? 0]; - bucketColumns.push({ - name: metricColumn.name, - }); + return { + bucketColumns, + metricColumn: visData.columns[matchingIndex + 1], + }; } + const metricAccessor = visParams?.dimensions?.metric.accessor ?? 0; + const metricColumn = visData.columns[metricAccessor]; return { - bucketColumns, metricColumn, + bucketColumns: [ + { + name: metricColumn.name, + }, + ], }; }; diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index e14ea1215a1247..77c2bc1c0da246 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -45,7 +45,10 @@ export const getConfig = ( // On small multiples we want the labels to only appear inside const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); - if (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) { + if ( + (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) && + visParams.labels.show + ) { config.linkLabel = { maxCount: 0 }; } return config; diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index fcec5fe7b4d87b..886861df15d614 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -128,7 +128,7 @@ export const getLayers = ( return String(d); }, sortPredicate: ([name1, node1]: ArrayEntry, [name2, node2]: ArrayEntry) => { - const params = col?.meta?.sourceParams?.params as SplitDimensionParams | undefined; + const params = col.meta?.sourceParams?.params as SplitDimensionParams | undefined; const sort: string | undefined = params?.orderBy; // metric sorting if (sort !== '_key') { From 1543312ff2b4e137b0c9789e6abd31553df8e79b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 5 May 2021 10:24:40 +0300 Subject: [PATCH 094/111] Add padding to the pie container --- src/plugins/vis_type_pie/public/chart.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index 5febeea3019cb4..f53343252aeb73 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -12,4 +12,5 @@ right: 0; bottom: 0; left: 0; + padding: $euiSizeS; } From a0087eca7dadb08ec3361a7d69c9d1a2e12238a6 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 5 May 2021 10:38:10 +0300 Subject: [PATCH 095/111] Add a max width to the container --- src/plugins/vis_type_pie/public/chart.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index f53343252aeb73..9f7dee0b4f8b87 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -13,4 +13,7 @@ bottom: 0; left: 0; padding: $euiSizeS; + max-width: 1024px; + margin-left: auto; + margin-right: auto; } From e96a5a1dfe8b7964836ecb2184062657c2876699 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 17 May 2021 11:13:02 +0300 Subject: [PATCH 096/111] Improve dashboard functional test --- src/plugins/vis_type_pie/public/chart.scss | 1 - test/functional/apps/dashboard/dashboard_state.ts | 9 ++++++--- test/functional/services/visualizations/pie_chart.ts | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_type_pie/public/chart.scss b/src/plugins/vis_type_pie/public/chart.scss index 9f7dee0b4f8b87..8c098b13581f50 100644 --- a/src/plugins/vis_type_pie/public/chart.scss +++ b/src/plugins/vis_type_pie/public/chart.scss @@ -13,7 +13,6 @@ bottom: 0; left: 0; padding: $euiSizeS; - max-width: 1024px; margin-left: auto; margin-right: auto; } diff --git a/test/functional/apps/dashboard/dashboard_state.ts b/test/functional/apps/dashboard/dashboard_state.ts index 241bade418d22e..0f7722925293b1 100644 --- a/test/functional/apps/dashboard/dashboard_state.ts +++ b/test/functional/apps/dashboard/dashboard_state.ts @@ -256,8 +256,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); describe('for embeddable config color parameters on a visualization', () => { + let originalPieSliceStyle = ''; it('updates a pie slice color on a soft refresh', async function () { await dashboardAddPanel.addVisualization(PIE_CHART_VIS_NAME); + + originalPieSliceStyle = await pieChart.getPieSliceStyle(`80,000`); await PageObjects.visChart.openLegendOptionColors( '80,000', `[data-title="${PIE_CHART_VIS_NAME}"]` @@ -298,9 +301,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const pieSliceStyle = await pieChart.getPieSliceStyle('80,000'); - const color = isNewChartsLibraryEnabled ? 'rgb(111, 135, 216)' : 'rgb(87, 193, 123)'; - // The default color that was stored with the visualization before any dashboard overrides. - expect(pieSliceStyle.indexOf(color)).to.be.greaterThan(-1); + + // After removing all overrides, pie slice style should match original. + expect(pieSliceStyle).to.be(originalPieSliceStyle); }); }); diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index 3f1b185444ca73..7c4239f4bd667a 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -93,7 +93,7 @@ export function PieChartProvider({ getService, getPageObjects }: FtrProviderCont const selectedSlice = slices.filter((slice) => { return slice.name.toString() === name.replace(',', ''); }); - return [selectedSlice[0].color]; + return selectedSlice[0].color; } const pieSlice = await this.getPieSlice(name); return await pieSlice.getAttribute('style'); From b928ef9bbab5457c499ae4b5870f2371526ec045 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 17 May 2021 11:25:58 +0300 Subject: [PATCH 097/111] Move the labels expression function to the pie plugin --- .../public/expression_functions/pie_labels.ts | 0 src/plugins/vis_type_pie/public/plugin.ts | 2 ++ src/plugins/vis_type_pie/public/types/types.ts | 6 ++---- src/plugins/visualizations/public/index.ts | 1 - src/plugins/visualizations/public/plugin.ts | 2 -- 5 files changed, 4 insertions(+), 7 deletions(-) rename src/plugins/{visualizations => vis_type_pie}/public/expression_functions/pie_labels.ts (100%) diff --git a/src/plugins/visualizations/public/expression_functions/pie_labels.ts b/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts similarity index 100% rename from src/plugins/visualizations/public/expression_functions/pie_labels.ts rename to src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts diff --git a/src/plugins/vis_type_pie/public/plugin.ts b/src/plugins/vis_type_pie/public/plugin.ts index 43239a3da29881..440a3a75a2eb19 100644 --- a/src/plugins/vis_type_pie/public/plugin.ts +++ b/src/plugins/vis_type_pie/public/plugin.ts @@ -13,6 +13,7 @@ import { ChartsPluginSetup } from '../../charts/public'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { DataPublicPluginStart } from '../../data/public'; import { LEGACY_CHARTS_LIBRARY } from '../../visualizations/common/constants'; +import { pieLabels as pieLabelsExpressionFunction } from './expression_functions/pie_labels'; import { createPieVisFn } from './pie_fn'; import { getPieVisRenderer } from './pie_renderer'; import { pieVisType } from './vis_type'; @@ -56,6 +57,7 @@ export class VisTypePiePlugin { expressions.registerRenderer( getPieVisRenderer({ theme: charts.theme, palettes: charts.palettes, getStartDeps }) ); + expressions.registerFunction(pieLabelsExpressionFunction); visualizations.createBaseVisualization( pieVisType({ showElasticChartsOptions: true, diff --git a/src/plugins/vis_type_pie/public/types/types.ts b/src/plugins/vis_type_pie/public/types/types.ts index 1b7594ff545841..f35f435a95b05f 100644 --- a/src/plugins/vis_type_pie/public/types/types.ts +++ b/src/plugins/vis_type_pie/public/types/types.ts @@ -9,10 +9,8 @@ import { Position } from '@elastic/charts'; import { UiCounterMetricType } from '@kbn/analytics'; import { DatatableColumn, SerializedFieldFormat } from '../../../expressions/public'; -import { - ExpressionValueVisDimension, - ExpressionValuePieLabels, -} from '../../../visualizations/public'; +import { ExpressionValueVisDimension } from '../../../visualizations/public'; +import { ExpressionValuePieLabels } from '../expression_functions/pie_labels'; import { PaletteOutput, ChartsPluginSetup } from '../../../charts/public'; export interface Dimension { diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 6fe7981d11b6ea..081023d0039e78 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -43,4 +43,3 @@ export { VisualizationListItem, VisualizationStage } from './vis_types/vis_type_ export { VISUALIZE_ENABLE_LABS_SETTING } from '../common/constants'; export { SavedVisState, VisParams } from '../common'; export { ExpressionValueVisDimension } from './expression_functions/vis_dimension'; -export { ExpressionValuePieLabels } from './expression_functions/pie_labels'; diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index 1261ffd353098a..c248ae180e8e66 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -33,7 +33,6 @@ import { import { TypesService } from './vis_types/types_service'; import { range as rangeExpressionFunction } from './expression_functions/range'; import { visDimension as visDimensionExpressionFunction } from './expression_functions/vis_dimension'; -import { pieLabels as pieLabelsExpressionFunction } from './expression_functions/pie_labels'; import { createStartServicesGetter, StartServicesGetter } from '../../kibana_utils/public'; import { createSavedVisLoader, SavedVisualizationsLoader } from './saved_visualizations'; @@ -137,7 +136,6 @@ export class VisualizationsPlugin expressions.registerFunction(rangeExpressionFunction); expressions.registerFunction(visDimensionExpressionFunction); - expressions.registerFunction(pieLabelsExpressionFunction); const embeddableFactory = new VisualizeEmbeddableFactory({ start }); embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); From 97b85623368c719df3df8f933a5d6eadfc1f2a86 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 17 May 2021 11:38:47 +0300 Subject: [PATCH 098/111] Fix i18n --- .../public/expression_functions/pie_labels.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts b/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts index 2005dc61f7cb06..41590f20653f07 100644 --- a/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts +++ b/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts @@ -43,14 +43,14 @@ export const pieLabels = (): ExpressionFunctionDefinition< ExpressionValuePieLabels > => ({ name: 'pielabels', - help: i18n.translate('visualizations.function.pieLabels.help', { + help: i18n.translate('visTypePie.function.pieLabels.help', { defaultMessage: 'Generates the pie labels object', }), type: 'pie_labels', args: { show: { types: ['boolean'], - help: i18n.translate('visualizations.function.pieLabels.show.help', { + help: i18n.translate('visTypePie.function.pieLabels.show.help', { defaultMessage: 'Displays the pie labels', }), required: true, @@ -58,34 +58,34 @@ export const pieLabels = (): ExpressionFunctionDefinition< position: { types: ['string'], default: 'default', - help: i18n.translate('visualizations.function.pieLabels.position.help', { + help: i18n.translate('visTypePie.function.pieLabels.position.help', { defaultMessage: 'Defines the label position', }), }, values: { types: ['boolean'], - help: i18n.translate('visualizations.function.pieLabels.values.help', { + help: i18n.translate('visTypePie.function.pieLabels.values.help', { defaultMessage: 'Displays the values inside the slices', }), default: true, }, percentDecimals: { types: ['number'], - help: i18n.translate('visualizations.function.pieLabels.percentDecimals.help', { + help: i18n.translate('visTypePie.function.pieLabels.percentDecimals.help', { defaultMessage: 'Defines the number of decimals that will appear on the values as percent', }), default: 2, }, last_level: { types: ['boolean'], - help: i18n.translate('visualizations.function.pieLabels.lastLevel.help', { + help: i18n.translate('visTypePie.function.pieLabels.lastLevel.help', { defaultMessage: 'Show top level labels only', }), default: true, }, truncate: { types: ['number', 'null'], - help: i18n.translate('visualizations.function.pieLabels.truncate.help', { + help: i18n.translate('visTypePie.function.pieLabels.truncate.help', { defaultMessage: 'Defines the number of characters that the slice value will display', }), default: null, @@ -93,7 +93,7 @@ export const pieLabels = (): ExpressionFunctionDefinition< valuesFormat: { types: ['string'], default: 'percent', - help: i18n.translate('visualizations.function.pieLabels.valuesFormat.help', { + help: i18n.translate('visTypePie.function.pieLabels.valuesFormat.help', { defaultMessage: 'Defines the format of the values', }), }, From 5bb1ef284881b10927b9f08bdafbe139a1e8b135 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 27 May 2021 16:27:28 +0300 Subject: [PATCH 099/111] Fix functional test --- test/functional/services/visualizations/pie_chart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index 74028b5e907fcf..f51492d29b4506 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -184,7 +184,7 @@ export class PieChartService extends FtrService { this.log.debug(`PieChart.expectPieChartLabels(${expectedLabels.join(',')})`); await this.retry.try(async () => { const pieData = await this.getPieChartLabels(); - expect(pieData).to.eql(expectedLabels); + expect(pieData.sort()).to.eql(expectedLabels); }); } } From 86b2e82b451c485be57240b21f3481bcece33ad2 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 10:09:44 +0300 Subject: [PATCH 100/111] Apply PR comments --- .../vis_type_pie/public/editor/components/pie.tsx | 6 ------ src/plugins/vis_type_pie/public/utils/get_layers.ts | 7 ++++++- test/functional/apps/visualize/_pie_chart.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index ada2816fc5d1cb..9b8f9806cbd470 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -41,12 +41,10 @@ function DecimalSlider({ paramName, value, setValue, - disabled, }: { value: number; paramName: ParamName; setValue: (paramName: ParamName, value: number) => void; - disabled: boolean; }) { return ( ({ max={10} showInput compressed - disabled={disabled} onChange={(e) => { setValue(paramName, Number(e.currentTarget.value)); }} @@ -276,9 +273,6 @@ const PieOptions = (props: PieOptionsProps) => { paramName="percentDecimals" value={stateParams.labels.percentDecimals ?? DEFAULT_PERCENT_DECIMALS} setValue={setLabels} - disabled={ - stateParams.labels.valuesFormat === ValueFormats.VALUE || !stateParams.labels.values - } /> )} diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 886861df15d614..f32e39a756e6a2 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -123,7 +123,12 @@ export const getLayers = ( }); } if (col.format) { - return formatter.deserialize(col.format).convert(d) ?? ''; + 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))}...`; + } } return String(d); }, diff --git a/test/functional/apps/visualize/_pie_chart.ts b/test/functional/apps/visualize/_pie_chart.ts index 337a48a380f39d..8f76e2765e42c9 100644 --- a/test/functional/apps/visualize/_pie_chart.ts +++ b/test/functional/apps/visualize/_pie_chart.ts @@ -15,6 +15,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const pieChart = getService('pieChart'); const inspector = getService('inspector'); + const browser = getService('browser'); + const kibanaServer = getService('kibanaServer'); + const PageObjects = getPageObjects([ 'common', 'visualize', @@ -25,9 +28,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ]); describe('pie chart', function () { + // Used to track flag before and after reset + let isNewChartsLibraryEnabled = false; const vizName1 = 'Visualization PieChart'; before(async function () { + isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled(); await PageObjects.visualize.initTests(); + if (isNewChartsLibraryEnabled) { + await kibanaServer.uiSettings.update({ + 'visualization:visualize:legacyChartsLibrary': false, + }); + await browser.refresh(); + } log.debug('navigateToApp visualize'); await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); From 785f3736a3a09652b001122214830fda5010ff91 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 10:33:27 +0300 Subject: [PATCH 101/111] Do not forget to also add the migration to them embeddable too :D --- .../server/embeddable/visualize_embeddable_factory.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts b/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts index 6f214745e12912..6a6d892eb9d4eb 100644 --- a/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts +++ b/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts @@ -13,6 +13,7 @@ import { commonAddSupportOfDualIndexSelectionModeInTSVB, commonHideTSVBLastValueIndicator, commonRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel, + commonMigrateVislibPie, } from '../migrations/visualization_common_migrations'; const byValueAddSupportOfDualIndexSelectionModeInTSVB = (state: SerializableState) => { @@ -36,6 +37,13 @@ const byValueRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel = (state: Serial }; }; +const byValueMigrateVislibPie = (state: SerializableState) => { + return { + ...state, + savedVis: commonMigrateVislibPie(state.savedVis), + }; +}; + export const visualizeEmbeddableFactory = (): EmbeddableRegistryDefinition => { return { id: 'visualization', @@ -47,6 +55,7 @@ export const visualizeEmbeddableFactory = (): EmbeddableRegistryDefinition => { byValueHideTSVBLastValueIndicator, byValueRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel )(state), + '7.14.0': (state) => flow(byValueMigrateVislibPie)(state), }, }; }; From a9d96e0db1aa07273504d0a583967d8f3740011a Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 13:50:22 +0300 Subject: [PATCH 102/111] Fix distinct colors for IP range layer --- .../vis_type_pie/public/utils/get_layers.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index f32e39a756e6a2..79f2db9977c361 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -14,6 +14,7 @@ import { ShapeTreeNode, ArrayEntry, } from '@elastic/charts'; +import { isEqual } from 'lodash'; import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public'; import { DataPublicPluginStart } from '../../../data/public'; import { DatatableRow } from '../../../expressions/public'; @@ -35,15 +36,19 @@ export const computeColor = ( const { parentSeries, allSeries } = getDistinctSeries(rows, columns); if (visParams.distinctColors) { - if (Object.keys(overwriteColors).includes(d.dataName.toString())) { - return overwriteColors[d.dataName]; + const dataName = d.dataName; + // console.dir(Object.keys(overwriteColors)); + if (Object.keys(overwriteColors).includes(dataName.toString())) { + return overwriteColors[dataName]; } - const index = allSeries.findIndex((name) => name === d.dataName); + // console.log(dataName.toString()); + + const index = allSeries.findIndex((name) => isEqual(name, dataName)); return palettes?.get(visParams.palette.name).getColor( [ { - name: d.dataName, - rankAtDepth: index > -1 ? allSeries.findIndex((name) => name === d.dataName) : 0, + name: dataName, + rankAtDepth: index > -1 ? index : 0, totalSeriesAtDepth: allSeries.length || 1, }, ], From a7c4bafef42f9329ed0db71cb024400b9807dc88 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 13:51:25 +0300 Subject: [PATCH 103/111] Remove console errors --- src/plugins/vis_type_pie/public/utils/get_layers.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 79f2db9977c361..c2073195269afe 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -37,11 +37,9 @@ export const computeColor = ( if (visParams.distinctColors) { const dataName = d.dataName; - // console.dir(Object.keys(overwriteColors)); if (Object.keys(overwriteColors).includes(dataName.toString())) { return overwriteColors[dataName]; } - // console.log(dataName.toString()); const index = allSeries.findIndex((name) => isEqual(name, dataName)); return palettes?.get(visParams.palette.name).getColor( From bd7e2d8cf3fca0a00e60b2b20c56619b55c1ed40 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 17:00:28 +0300 Subject: [PATCH 104/111] Fix small mulitples colors with multiple layers --- src/plugins/vis_type_pie/public/utils/get_layers.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index c2073195269afe..fb3f315a7d91bf 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -42,12 +42,15 @@ export const computeColor = ( } const index = allSeries.findIndex((name) => isEqual(name, dataName)); + const isSplitParentLayer = isSplitChart && parentSeries.includes(dataName); return palettes?.get(visParams.palette.name).getColor( [ { name: dataName, - rankAtDepth: index > -1 ? index : 0, - totalSeriesAtDepth: allSeries.length || 1, + rankAtDepth: isSplitParentLayer + ? parentSeries.findIndex((name) => name === dataName) : index > -1 ? index : 0, + totalSeriesAtDepth: isSplitParentLayer + ? parentSeries.length : allSeries.length || 1, }, ], { From 48410bbbe715f79658fa4f28384c0d28b7082f1e Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 28 May 2021 17:43:16 +0300 Subject: [PATCH 105/111] Fix lint problem --- src/plugins/vis_type_pie/public/utils/get_layers.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index fb3f315a7d91bf..50269e4bb241c7 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -48,9 +48,11 @@ export const computeColor = ( { name: dataName, rankAtDepth: isSplitParentLayer - ? parentSeries.findIndex((name) => name === dataName) : index > -1 ? index : 0, - totalSeriesAtDepth: isSplitParentLayer - ? parentSeries.length : allSeries.length || 1, + ? parentSeries.findIndex((name) => name === dataName) + : index > -1 + ? index + : 0, + totalSeriesAtDepth: isSplitParentLayer ? parentSeries.length : allSeries.length || 1, }, ], { From b2982f46b2ad298671d76fcec0d130025bb6cc36 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 31 May 2021 10:20:10 +0300 Subject: [PATCH 106/111] Fix problems created from merging with master --- src/plugins/vis_type_pie/public/utils/get_layers.test.ts | 4 ++-- src/plugins/vis_type_pie/public/utils/get_layers.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.test.ts b/src/plugins/vis_type_pie/public/utils/get_layers.test.ts index 535ecbbc384b35..e0658eaa295f95 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.test.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.test.ts @@ -18,8 +18,8 @@ export const getPaletteRegistry = () => { const mockPalette1: jest.Mocked = { id: 'default', title: 'My Palette', - getColor: jest.fn((layer: SeriesLayer[]) => colors[layer[0].rankAtDepth]), - getColors: jest.fn((num: number) => colors), + getCategoricalColor: jest.fn((layer: SeriesLayer[]) => colors[layer[0].rankAtDepth]), + getCategoricalColors: jest.fn((num: number) => colors), toExpression: jest.fn(() => ({ type: 'expression', chain: [ diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 50269e4bb241c7..946c2600f9edec 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -43,7 +43,7 @@ export const computeColor = ( const index = allSeries.findIndex((name) => isEqual(name, dataName)); const isSplitParentLayer = isSplitChart && parentSeries.includes(dataName); - return palettes?.get(visParams.palette.name).getColor( + return palettes?.get(visParams.palette.name).getCategoricalColor( [ { name: dataName, @@ -90,7 +90,7 @@ export const computeColor = ( if (overwriteColor) { return lightenColor(overwriteColor, seriesLayers.length, columns.length); } - return palettes?.get(visParams.palette.name).getColor(seriesLayers, { + return palettes?.get(visParams.palette.name).getCategoricalColor(seriesLayers, { behindText: visParams.labels.show, maxDepth: columns.length, totalSeries: rows.length, From 8ea3f607dd56ac8f8e32a2f824cea8143a520402 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 1 Jun 2021 10:14:26 +0300 Subject: [PATCH 107/111] Address PR comments --- src/plugins/vis_type_pie/public/utils/get_config.ts | 2 +- src/plugins/vis_type_pie/public/utils/get_layers.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 77c2bc1c0da246..4c2c751e242789 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -17,7 +17,7 @@ export const getConfig = ( partitionLayout: PartitionLayout.sunburst, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, outerSizeRatio: 1, - specialFirstInnermostSector: true, + specialFirstInnermostSector: false, minFontSize: 10, maxFontSize: 16, linkLabel: { diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 946c2600f9edec..27e2321379ea8a 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -143,6 +143,9 @@ export const getLayers = ( sortPredicate: ([name1, node1]: ArrayEntry, [name2, node2]: ArrayEntry) => { const params = col.meta?.sourceParams?.params as SplitDimensionParams | undefined; const sort: string | undefined = params?.orderBy; + // unconditionally put "Other" to the end (as the "Other" slice may be larger than a regular slice, yet should be at the end) + if (name1 === '__other__' && name2 !== '__other__') return 1; + if (name2 === '__other__' && name1 !== '__other__') return -1; // metric sorting if (sort !== '_key') { if (params?.order === 'desc') { From c59349aeee19d0a9cbcf784e5b17e59e2378c6a8 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 3 Jun 2021 14:23:36 +0300 Subject: [PATCH 108/111] Change the config in order the pie chart to not appear so huge on the editor --- .../vis_type_pie/public/pie_component.tsx | 23 ++++++++++++++--- .../vis_type_pie/public/types/types.ts | 5 ++++ .../vis_type_pie/public/utils/get_config.ts | 25 ++++++++++++++++--- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index e6edefef3ccd58..504a5ad736f3fd 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { memo, useCallback, useMemo, useState, useEffect } from 'react'; +import React, { memo, useCallback, useMemo, useState, useEffect, useRef } from 'react'; import { Chart, @@ -30,7 +30,7 @@ import { DataPublicPluginStart, FieldFormat } from '../../data/public'; import type { PersistedState } from '../../visualizations/public'; import { Datatable, DatatableColumn, IInterpreterRenderHandlers } from '../../expressions/public'; import { DEFAULT_PERCENT_DECIMALS } from '../common'; -import { PieVisParams, BucketColumns, ValueFormats } from './types'; +import { PieVisParams, BucketColumns, ValueFormats, PieContainerDimensions } from './types'; import { getColorPicker, getLayers, @@ -75,6 +75,17 @@ const PieComponent = (props: PieComponentProps) => { props.visParams.addLegend == null ? false : props.visParams.addLegend; return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; }); + const [dimensions, setDimensions] = useState(); + + const parentRef = useRef(null); + + useEffect(() => { + if (parentRef && parentRef.current) { + const parentHeight = parentRef.current!.getBoundingClientRect().height; + const parentWidth = parentRef.current!.getBoundingClientRect().width; + setDimensions({ width: parentWidth, height: parentHeight }); + } + }, [parentRef]); const onRenderChange = useCallback( (isRendered) => { @@ -218,7 +229,11 @@ const PieComponent = (props: PieComponentProps) => { syncColors, ] ); - const config = useMemo(() => getConfig(visParams, chartTheme), [chartTheme, visParams]); + const config = useMemo(() => getConfig(visParams, chartTheme, dimensions), [ + chartTheme, + visParams, + dimensions, + ]); const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, }; @@ -269,7 +284,7 @@ const PieComponent = (props: PieComponentProps) => { return (
-
+
+ chartTheme: RecursivePartial, + dimensions?: PieContainerDimensions ): RecursivePartial => { + const maxSize = 900; + const usingMargin = dimensions + ? { + margin: { + top: (1 - Math.min(1, maxSize / dimensions?.height)) / 2, + bottom: (1 - Math.min(1, maxSize / dimensions?.height)) / 2, + left: (1 - Math.min(1, maxSize / dimensions?.width)) / 2, + right: (1 - Math.min(1, maxSize / dimensions?.width)) / 2, + }, + } + : null; + + const usingOuterSizeRatio = dimensions + ? { + outerSizeRatio: maxSize / Math.min(dimensions?.width, dimensions?.height), + } + : null; const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, - outerSizeRatio: 1, + ...usingOuterSizeRatio, specialFirstInnermostSector: false, minFontSize: 10, maxFontSize: 16, @@ -30,6 +48,7 @@ export const getConfig = ( sectorLineWidth: 1.5, circlePadding: 4, emptySizeRatio: visParams.isDonut ? 0.3 : 0, + ...usingMargin, }; if (!visParams.labels.show) { // Force all labels to be linked, then prevent links from showing From 5e58f17d24706e92df0e3f77fc69198b74204d23 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 3 Jun 2021 14:49:07 +0300 Subject: [PATCH 109/111] Address PR comments --- .../public/__snapshots__/to_ast.test.ts.snap | 2 +- .../public/expression_functions/pie_labels.ts | 6 +-- .../vis_type_pie/public/pie_component.tsx | 4 +- src/plugins/vis_type_pie/public/to_ast.ts | 2 +- .../vis_type_pie/public/utils/get_config.ts | 38 ++++++++++--------- .../vis_type_pie/public/utils/get_layers.ts | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap index 0f4581a4157a07..0c8398a142027c 100644 --- a/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap +++ b/src/plugins/vis_type_pie/public/__snapshots__/to_ast.test.ts.snap @@ -70,7 +70,7 @@ Object { "chain": Array [ Object { "arguments": Object { - "last_level": Array [ + "lastLevel": Array [ true, ], "show": Array [ diff --git a/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts b/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts index 41590f20653f07..269d5d5f779d6c 100644 --- a/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts +++ b/src/plugins/vis_type_pie/public/expression_functions/pie_labels.ts @@ -19,7 +19,7 @@ interface Arguments { values: boolean; truncate: number | null; valuesFormat: string; - last_level: boolean; + lastLevel: boolean; percentDecimals: number; } @@ -76,7 +76,7 @@ export const pieLabels = (): ExpressionFunctionDefinition< }), default: 2, }, - last_level: { + lastLevel: { types: ['boolean'], help: i18n.translate('visTypePie.function.pieLabels.lastLevel.help', { defaultMessage: 'Show top level labels only', @@ -107,7 +107,7 @@ export const pieLabels = (): ExpressionFunctionDefinition< values: args.values, truncate: args.truncate, valuesFormat: args.valuesFormat, - last_level: args.last_level, + last_level: args.lastLevel, }; }, }); diff --git a/src/plugins/vis_type_pie/public/pie_component.tsx b/src/plugins/vis_type_pie/public/pie_component.tsx index 504a5ad736f3fd..b79eed2087a168 100644 --- a/src/plugins/vis_type_pie/public/pie_component.tsx +++ b/src/plugins/vis_type_pie/public/pie_component.tsx @@ -237,9 +237,7 @@ const PieComponent = (props: PieComponentProps) => { const tooltip: TooltipProps = { type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, }; - const legendPosition = useMemo(() => visParams.legendPosition ?? Position.Right, [ - visParams.legendPosition, - ]); + const legendPosition = visParams.legendPosition ?? Position.Right; const legendColorPicker = useMemo( () => diff --git a/src/plugins/vis_type_pie/public/to_ast.ts b/src/plugins/vis_type_pie/public/to_ast.ts index 41b345d4aefd3a..e8c9f301b4366d 100644 --- a/src/plugins/vis_type_pie/public/to_ast.ts +++ b/src/plugins/vis_type_pie/public/to_ast.ts @@ -26,7 +26,7 @@ const prepareDimension = (params: SchemaConfig) => { const prepareLabels = (params: LabelsParams) => { const pieLabels = buildExpressionFunction('pielabels', { show: params.show, - last_level: params.last_level, + lastLevel: params.last_level, values: params.values, truncate: params.truncate, }); diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index 2ce649feb48cf4..d81f2db570a475 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -8,29 +8,33 @@ import { PartitionConfig, PartitionLayout, RecursivePartial, Theme } from '@elastic/charts'; import { LabelPositions, PieVisParams, PieContainerDimensions } from '../types'; +const MAX_SIZE = 900; export const getConfig = ( visParams: PieVisParams, chartTheme: RecursivePartial, dimensions?: PieContainerDimensions ): RecursivePartial => { - const maxSize = 900; - const usingMargin = dimensions - ? { - margin: { - top: (1 - Math.min(1, maxSize / dimensions?.height)) / 2, - bottom: (1 - Math.min(1, maxSize / dimensions?.height)) / 2, - left: (1 - Math.min(1, maxSize / dimensions?.width)) / 2, - right: (1 - Math.min(1, maxSize / dimensions?.width)) / 2, - }, - } - : null; + // On small multiples we want the labels to only appear inside + const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); + const usingMargin = + dimensions && !isSplitChart + ? { + margin: { + top: (1 - Math.min(1, MAX_SIZE / dimensions?.height)) / 2, + bottom: (1 - Math.min(1, MAX_SIZE / dimensions?.height)) / 2, + left: (1 - Math.min(1, MAX_SIZE / dimensions?.width)) / 2, + right: (1 - Math.min(1, MAX_SIZE / dimensions?.width)) / 2, + }, + } + : null; - const usingOuterSizeRatio = dimensions - ? { - outerSizeRatio: maxSize / Math.min(dimensions?.width, dimensions?.height), - } - : null; + const usingOuterSizeRatio = + dimensions && !isSplitChart + ? { + outerSizeRatio: MAX_SIZE / Math.min(dimensions?.width, dimensions?.height), + } + : null; const config: RecursivePartial = { partitionLayout: PartitionLayout.sunburst, fontFamily: chartTheme.barSeriesStyle?.displayValue?.fontFamily, @@ -62,8 +66,6 @@ export const getConfig = ( }; } - // On small multiples we want the labels to only appear inside - const isSplitChart = Boolean(visParams.dimensions.splitColumn || visParams.dimensions.splitRow); if ( (visParams.labels.position === LabelPositions.INSIDE || isSplitChart) && visParams.labels.show diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 27e2321379ea8a..27dcf2d379811d 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -135,7 +135,7 @@ export const getLayers = ( if (visParams.labels.truncate && formattedLabel.length <= visParams.labels.truncate) { return formattedLabel; } else { - return `${formattedLabel.slice(0, Number(visParams.labels.truncate))}...`; + return `${formattedLabel.slice(0, Number(visParams.labels.truncate))}\u2026`; } } return String(d); From d9c98a3df152bff50460539171c5fd2c275491f5 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 3 Jun 2021 15:12:13 +0300 Subject: [PATCH 110/111] Change the max percentage digits to 4 --- src/plugins/vis_type_pie/public/editor/components/pie.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/editor/components/pie.tsx b/src/plugins/vis_type_pie/public/editor/components/pie.tsx index 9b8f9806cbd470..8ce4f4defbaed8 100644 --- a/src/plugins/vis_type_pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_type_pie/public/editor/components/pie.tsx @@ -57,7 +57,7 @@ function DecimalSlider({ { From 6facbb503c079b2523e8ea9314890729f9a4208d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 3 Jun 2021 16:29:01 +0300 Subject: [PATCH 111/111] Change the max size to 1000 --- src/plugins/vis_type_pie/public/utils/get_config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_type_pie/public/utils/get_config.ts b/src/plugins/vis_type_pie/public/utils/get_config.ts index d81f2db570a475..a8a4edb01cd9c8 100644 --- a/src/plugins/vis_type_pie/public/utils/get_config.ts +++ b/src/plugins/vis_type_pie/public/utils/get_config.ts @@ -8,7 +8,7 @@ import { PartitionConfig, PartitionLayout, RecursivePartial, Theme } from '@elastic/charts'; import { LabelPositions, PieVisParams, PieContainerDimensions } from '../types'; -const MAX_SIZE = 900; +const MAX_SIZE = 1000; export const getConfig = ( visParams: PieVisParams,