[VisTypePie] Fixes color migrations of pie charts (#104373)
* [Pie] fix color migrations of pie charts * Fix color picker * Fix functional test * revert * Apply PR comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
24afb1a52d
commit
186b936fbb
|
@ -10,7 +10,7 @@ import React, { useCallback } from 'react';
|
||||||
import Color from 'color';
|
import Color from 'color';
|
||||||
import { LegendColorPicker, Position } from '@elastic/charts';
|
import { LegendColorPicker, Position } from '@elastic/charts';
|
||||||
import { PopoverAnchorPosition, EuiPopover, EuiOutsideClickDetector } from '@elastic/eui';
|
import { PopoverAnchorPosition, EuiPopover, EuiOutsideClickDetector } from '@elastic/eui';
|
||||||
import { DatatableRow } from '../../../expressions/public';
|
import type { DatatableRow } from '../../../expressions/public';
|
||||||
import type { PersistedState } from '../../../visualizations/public';
|
import type { PersistedState } from '../../../visualizations/public';
|
||||||
import { ColorPicker } from '../../../charts/public';
|
import { ColorPicker } from '../../../charts/public';
|
||||||
import { BucketColumns } from '../types';
|
import { BucketColumns } from '../types';
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
*/
|
*/
|
||||||
import { ShapeTreeNode } from '@elastic/charts';
|
import { ShapeTreeNode } from '@elastic/charts';
|
||||||
import { PaletteDefinition, SeriesLayer } from '../../../charts/public';
|
import { PaletteDefinition, SeriesLayer } from '../../../charts/public';
|
||||||
|
import { dataPluginMock } from '../../../data/public/mocks';
|
||||||
|
import type { DataPublicPluginStart } from '../../../data/public';
|
||||||
import { computeColor } from './get_layers';
|
import { computeColor } from './get_layers';
|
||||||
import { createMockVisData, createMockBucketColumns, createMockPieParams } from '../mocks';
|
import { createMockVisData, createMockBucketColumns, createMockPieParams } from '../mocks';
|
||||||
|
|
||||||
|
@ -14,6 +16,20 @@ const visData = createMockVisData();
|
||||||
const buckets = createMockBucketColumns();
|
const buckets = createMockBucketColumns();
|
||||||
const visParams = createMockPieParams();
|
const visParams = createMockPieParams();
|
||||||
const colors = ['color1', 'color2', 'color3', 'color4'];
|
const colors = ['color1', 'color2', 'color3', 'color4'];
|
||||||
|
const dataMock = dataPluginMock.createStartContract();
|
||||||
|
interface RangeProps {
|
||||||
|
gte: number;
|
||||||
|
lt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataMock.fieldFormats = ({
|
||||||
|
deserialize: jest.fn(() => ({
|
||||||
|
convert: jest.fn((s: RangeProps) => {
|
||||||
|
return `≥ ${s.gte} and < ${s.lt}`;
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
} as unknown) as DataPublicPluginStart['fieldFormats'];
|
||||||
|
|
||||||
export const getPaletteRegistry = () => {
|
export const getPaletteRegistry = () => {
|
||||||
const mockPalette1: jest.Mocked<PaletteDefinition> = {
|
const mockPalette1: jest.Mocked<PaletteDefinition> = {
|
||||||
id: 'default',
|
id: 'default',
|
||||||
|
@ -60,7 +76,8 @@ describe('computeColor', () => {
|
||||||
visData.rows,
|
visData.rows,
|
||||||
visParams,
|
visParams,
|
||||||
getPaletteRegistry(),
|
getPaletteRegistry(),
|
||||||
false
|
false,
|
||||||
|
dataMock.fieldFormats
|
||||||
);
|
);
|
||||||
expect(color).toEqual(colors[0]);
|
expect(color).toEqual(colors[0]);
|
||||||
});
|
});
|
||||||
|
@ -84,7 +101,8 @@ describe('computeColor', () => {
|
||||||
visData.rows,
|
visData.rows,
|
||||||
visParams,
|
visParams,
|
||||||
getPaletteRegistry(),
|
getPaletteRegistry(),
|
||||||
false
|
false,
|
||||||
|
dataMock.fieldFormats
|
||||||
);
|
);
|
||||||
expect(color).toEqual('color3');
|
expect(color).toEqual('color3');
|
||||||
});
|
});
|
||||||
|
@ -107,8 +125,60 @@ describe('computeColor', () => {
|
||||||
visData.rows,
|
visData.rows,
|
||||||
visParams,
|
visParams,
|
||||||
getPaletteRegistry(),
|
getPaletteRegistry(),
|
||||||
false
|
false,
|
||||||
|
dataMock.fieldFormats
|
||||||
);
|
);
|
||||||
expect(color).toEqual('#000028');
|
expect(color).toEqual('#000028');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns the overwriteColor for older visualizations with formatted values', () => {
|
||||||
|
const d = ({
|
||||||
|
dataName: {
|
||||||
|
gte: 1000,
|
||||||
|
lt: 2000,
|
||||||
|
},
|
||||||
|
depth: 1,
|
||||||
|
sortIndex: 0,
|
||||||
|
parent: {
|
||||||
|
children: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
gte: 1000,
|
||||||
|
lt: 2000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
gte: 2000,
|
||||||
|
lt: 3000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
depth: 0,
|
||||||
|
sortIndex: 0,
|
||||||
|
},
|
||||||
|
} as unknown) as ShapeTreeNode;
|
||||||
|
const visParamsNew = {
|
||||||
|
...visParams,
|
||||||
|
distinctColors: true,
|
||||||
|
};
|
||||||
|
const color = computeColor(
|
||||||
|
d,
|
||||||
|
true,
|
||||||
|
{ '≥ 1000 and < 2000': '#3F6833' },
|
||||||
|
buckets,
|
||||||
|
visData.rows,
|
||||||
|
visParamsNew,
|
||||||
|
getPaletteRegistry(),
|
||||||
|
false,
|
||||||
|
dataMock.fieldFormats,
|
||||||
|
{
|
||||||
|
id: 'range',
|
||||||
|
params: {
|
||||||
|
id: 'number',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect(color).toEqual('#3F6833');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,9 +15,9 @@ import {
|
||||||
} from '@elastic/charts';
|
} from '@elastic/charts';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public';
|
import { SeriesLayer, PaletteRegistry, lightenColor } from '../../../charts/public';
|
||||||
import { DataPublicPluginStart } from '../../../data/public';
|
import type { DataPublicPluginStart } from '../../../data/public';
|
||||||
import { DatatableRow } from '../../../expressions/public';
|
import type { DatatableRow } from '../../../expressions/public';
|
||||||
import { BucketColumns, PieVisParams, SplitDimensionParams } from '../types';
|
import type { BucketColumns, PieVisParams, SplitDimensionParams } from '../types';
|
||||||
import { getDistinctSeries } from './get_distinct_series';
|
import { getDistinctSeries } from './get_distinct_series';
|
||||||
|
|
||||||
const EMPTY_SLICE = Symbol('empty_slice');
|
const EMPTY_SLICE = Symbol('empty_slice');
|
||||||
|
@ -30,14 +30,33 @@ export const computeColor = (
|
||||||
rows: DatatableRow[],
|
rows: DatatableRow[],
|
||||||
visParams: PieVisParams,
|
visParams: PieVisParams,
|
||||||
palettes: PaletteRegistry | null,
|
palettes: PaletteRegistry | null,
|
||||||
syncColors: boolean
|
syncColors: boolean,
|
||||||
|
formatter: DataPublicPluginStart['fieldFormats'],
|
||||||
|
format?: BucketColumns['format']
|
||||||
) => {
|
) => {
|
||||||
const { parentSeries, allSeries } = getDistinctSeries(rows, columns);
|
const { parentSeries, allSeries } = getDistinctSeries(rows, columns);
|
||||||
|
const dataName = d.dataName;
|
||||||
|
|
||||||
|
let formattedLabel = '';
|
||||||
|
if (format) {
|
||||||
|
formattedLabel = formatter.deserialize(format).convert(dataName) ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
if (visParams.distinctColors) {
|
if (visParams.distinctColors) {
|
||||||
const dataName = d.dataName;
|
let overwriteColor;
|
||||||
|
// this is for supporting old visualizations (created by vislib plugin)
|
||||||
|
// it seems that there for some aggs, the uiState saved from vislib is
|
||||||
|
// different than the es-charts handle it
|
||||||
|
if (overwriteColors.hasOwnProperty(formattedLabel)) {
|
||||||
|
overwriteColor = overwriteColors[formattedLabel];
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(overwriteColors).includes(dataName.toString())) {
|
if (Object.keys(overwriteColors).includes(dataName.toString())) {
|
||||||
return overwriteColors[dataName];
|
overwriteColor = overwriteColors[dataName];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overwriteColor) {
|
||||||
|
return overwriteColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const index = allSeries.findIndex((name) => isEqual(name, dataName));
|
const index = allSeries.findIndex((name) => isEqual(name, dataName));
|
||||||
|
@ -80,6 +99,13 @@ export const computeColor = (
|
||||||
}
|
}
|
||||||
|
|
||||||
let overwriteColor;
|
let overwriteColor;
|
||||||
|
// this is for supporting old visualizations (created by vislib plugin)
|
||||||
|
// it seems that there for some aggs, the uiState saved from vislib is
|
||||||
|
// different than the es-charts handle it
|
||||||
|
if (overwriteColors.hasOwnProperty(formattedLabel)) {
|
||||||
|
overwriteColor = overwriteColors[formattedLabel];
|
||||||
|
}
|
||||||
|
|
||||||
seriesLayers.forEach((layer) => {
|
seriesLayers.forEach((layer) => {
|
||||||
if (Object.keys(overwriteColors).includes(layer.name)) {
|
if (Object.keys(overwriteColors).includes(layer.name)) {
|
||||||
overwriteColor = overwriteColors[layer.name];
|
overwriteColor = overwriteColors[layer.name];
|
||||||
|
@ -141,7 +167,7 @@ export const getLayers = (
|
||||||
if (name1 === '__other__' && name2 !== '__other__') return 1;
|
if (name1 === '__other__' && name2 !== '__other__') return 1;
|
||||||
if (name2 === '__other__' && name1 !== '__other__') return -1;
|
if (name2 === '__other__' && name1 !== '__other__') return -1;
|
||||||
// metric sorting
|
// metric sorting
|
||||||
if (sort !== '_key') {
|
if (sort && sort !== '_key') {
|
||||||
if (params?.order === 'desc') {
|
if (params?.order === 'desc') {
|
||||||
return node2.value - node1.value;
|
return node2.value - node1.value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +195,9 @@ export const getLayers = (
|
||||||
rows,
|
rows,
|
||||||
visParams,
|
visParams,
|
||||||
palettes,
|
palettes,
|
||||||
syncColors
|
syncColors,
|
||||||
|
formatter,
|
||||||
|
col.format
|
||||||
);
|
);
|
||||||
|
|
||||||
return outputColor || 'rgba(0,0,0,0)';
|
return outputColor || 'rgba(0,0,0,0)';
|
||||||
|
|
Loading…
Reference in a new issue