Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,38 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { DatatableRow } from '@kbn/expressions-plugin/common';
import { DatatableColumn, DatatableRow } from '@kbn/expressions-plugin/common';
import { getColorCategories } from './color_categories';

const extensions = ['gz', 'css', '', 'rpm', 'deb', 'zip', null];
const getExtension = (i: number) => extensions[i % extensions.length];
const getNextExtension = (() => {
let i = 0;
const extensions = ['gz', 'css', '', 'rpm', 'deb', 'zip', null];
return () => extensions[i++ % extensions.length];
})();

const basicDatatableRows: DatatableRow[] = Array.from({ length: 30 }).map((_, i) => ({
count: i,
extension: getExtension(i),
}));

const isTransposedDatatableRows: DatatableRow[] = Array.from({ length: 30 }).map((_, i) => ({
count: i,
['safari---extension']: getExtension(i),
['chrome---extension']: getExtension(i + 1),
['firefox---extension']: getExtension(i + 2),
}));
const basicDatatable = {
columns: ['count', 'extension'].map((id) => ({ id } as DatatableColumn)),
rows: Array.from({ length: 10 }).map((_, i) => ({
count: i,
extension: getNextExtension(),
})) as DatatableRow[],
};

describe('getColorCategories', () => {
it('should return all categories from datatable rows', () => {
expect(getColorCategories(basicDatatableRows, 'extension')).toEqual([
'gz',
'css',
'',
'rpm',
'deb',
'zip',
'null',
]);
it('should return no categories when accessor is undefined', () => {
expect(getColorCategories(basicDatatable.rows)).toEqual([]);
});

it('should exclude selected categories from datatable rows', () => {
expect(getColorCategories(basicDatatableRows, 'extension', false, ['', null])).toEqual([
'gz',
'css',
'rpm',
'deb',
'zip',
]);
it('should return no categories when accessor is not found', () => {
expect(getColorCategories(basicDatatable.rows, 'N/A')).toEqual([]);
});

it('should return no categories when no rows are defined', () => {
expect(getColorCategories(undefined, 'extension')).toEqual([]);
});

it('should return categories across all transpose columns of datatable rows', () => {
expect(getColorCategories(isTransposedDatatableRows, 'extension', true)).toEqual([
it('should return all categories from non-transpose datatable', () => {
expect(getColorCategories(basicDatatable.rows, 'extension')).toEqual([
'gz',
'css',
'',
Expand All @@ -60,8 +49,8 @@ describe('getColorCategories', () => {
]);
});

it('should exclude selected categories across all transpose columns of datatable rows', () => {
expect(getColorCategories(isTransposedDatatableRows, 'extension', true, ['', null])).toEqual([
it('should exclude selected categories from non-transpose datatable', () => {
expect(getColorCategories(basicDatatable.rows, 'extension', ['', null])).toEqual([
'gz',
'css',
'rpm',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,27 @@ import { isMultiFieldKey } from '@kbn/data-plugin/common';
/**
* Get the stringified version of all the categories that needs to be colored in the chart.
* Multifield keys will return as array of string and simple fields (numeric, string) will be returned as a plain unformatted string.
*
* Note: This does **NOT** support transposed columns
*/
export function getColorCategories(
rows: DatatableRow[],
rows: DatatableRow[] = [],
accessor?: string,
isTransposed?: boolean,
exclude?: any[]
): Array<string | string[]> {
const ids = isTransposed
? Object.keys(rows[0]).filter((key) => accessor && key.endsWith(accessor))
: accessor
? [accessor]
: [];
if (!accessor) return [];

return rows
.flatMap((r) =>
ids
.map((id) => r[id])
.filter((v) => !(v === undefined || exclude?.includes(v)))
.map((v) => {
// The categories needs to be stringified in their unformatted version.
// We can't distinguish between a number and a string from a text input and the match should
// work with both numeric field values and string values.
const key = (isMultiFieldKey(v) ? v.keys : [v]).map(String);
const stringifiedKeys = key.join(',');
return { key, stringifiedKeys };
})
)
.filter(({ [accessor]: v }) => !(v === undefined || exclude?.includes(v)))
.map((r) => {
const v = r[accessor];
// The categories needs to be stringified in their unformatted version.
// We can't distinguish between a number and a string from a text input and the match should
// work with both numeric field values and string values.
const key = (isMultiFieldKey(v) ? v.keys : [v]).map(String);
const stringifiedKeys = key.join(',');
return { key, stringifiedKeys };
})
.reduce<{ keys: Set<string>; categories: Array<string | string[]> }>(
(acc, { key, stringifiedKeys }) => {
if (!acc.keys.has(stringifiedKeys)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function TableDimensionEditor(props: TableDimensionEditorProps) {
};
// need to tell the helper that the colorStops are required to display
const displayStops = applyPaletteParams(props.paletteService, activePalette, currentMinMax);
const categories = getColorCategories(currentData?.rows ?? [], accessor, false, [null]);
const categories = getColorCategories(currentData?.rows, accessor, [null]);

if (activePalette.name !== CUSTOM_PALETTE && activePalette.params?.stops) {
activePalette.params.stops = applyPaletteParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { ClickTriggerEvent } from '@kbn/charts-plugin/public';
import { IconChartDatatable } from '@kbn/chart-icons';
import useObservable from 'react-use/lib/useObservable';
import { getColorCategories } from '@kbn/chart-expressions-common';
import { getOriginalId, isTransposeId } from '@kbn/transpose-utils';
import { getOriginalId } from '@kbn/transpose-utils';
import { CoreTheme } from '@kbn/core/public';
import { getKbnPalettes } from '@kbn/palettes';
import type { LensTableRowContextMenuEvent } from '../../../types';
Expand Down Expand Up @@ -405,16 +405,12 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
const dataType = getFieldMetaFromDatatable(firstLocalTable, originalId)?.type;
const isBucketed = bucketedColumns.some((id) => id === columnId);
const colorByTerms = shouldColorByTerms(dataType, isBucketed);

const categoryRows = (untransposedDataRef.current ?? firstLocalTable)?.rows;
const data: ColorMappingInputData = colorByTerms
? {
type: 'categories',
categories: getColorCategories(
firstLocalTable.rows,
originalId,
isTransposeId(columnId),
[null]
),
// Must use non-transposed data here to correctly collate categories across transposed columns
categories: getColorCategories(categoryRows, originalId, [null]),
}
: {
type: 'ranges',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
currentLayer.colorMapping
);
const table = props.frame.activeData?.[currentLayer.layerId];
const splitCategories = getColorCategories(table?.rows ?? [], props.accessor);
const splitCategories = getColorCategories(table?.rows, props.accessor);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function TagsDimensionEditor({
state.colorMapping
);
const table = frame.activeData?.[state.layerId];
const splitCategories = getColorCategories(table?.rows ?? [], state.tagAccessor);
const splitCategories = getColorCategories(table?.rows, state.tagAccessor);

const setColorMapping = useCallback(
(colorMapping?: ColorMapping.Config) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function DataDimensionEditor(

const table = props.frame.activeData?.[layer.layerId];
const { splitAccessor } = layer;
const splitCategories = getColorCategories(table?.rows ?? [], splitAccessor);
const splitCategories = getColorCategories(table?.rows, splitAccessor);

if (props.groupId === 'breakdown') {
return !layer.collapseFn ? (
Expand Down