Skip to content

Commit

Permalink
Added empty filters if x-axis is not defined.
Browse files Browse the repository at this point in the history
- Added empty filters if y-axis is defined, but x-axis is not and if no x/y-axis was defined.
- Added/fixed tests.
  • Loading branch information
Kuznietsov committed Oct 27, 2022
1 parent 55f0c45 commit e975faa
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,10 @@ describe('getConfiguration', () => {
vis = sampleHeatmapVis as unknown as Vis<HeatmapVisParams>;
});

test('should return null if yColumn is defined, but xColumn is not', async () => {
const result = await getConfiguration(layerId, vis, {
metrics: [metric.columnId],
buckets: { all: [xColumn.columnId, yColumn.columnId], customBuckets: {} },
columns: [metric, { ...xColumn, isBucketed: false }, yColumn],
});

expect(result).toBeNull();
});

test('should return valid configuration', async () => {
const result = await getConfiguration(layerId, vis, {
metrics: [metric.columnId],
buckets: { all: [xColumn.columnId, yColumn.columnId], customBuckets: {} },
columns: [metric, xColumn, yColumn],
buckets: [xColumn.columnId, yColumn.columnId],
});
expect(result).toEqual({
gridConfig: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { Column, HeatmapConfiguration } from '@kbn/visualizations-plugin/common';
import { HeatmapConfiguration } from '@kbn/visualizations-plugin/common';
import { Vis } from '@kbn/visualizations-plugin/public';
import { HeatmapVisParams } from '../../types';
import { getPaletteForHeatmap } from './palette';
Expand All @@ -17,22 +17,14 @@ export const getConfiguration = async (
{
metrics,
buckets,
columns,
}: {
metrics: string[];
buckets: {
all: string[];
customBuckets: Record<string, string>;
};
columns: Column[];
buckets: string[];
}
): Promise<HeatmapConfiguration | null> => {
): Promise<HeatmapConfiguration> => {
const [valueAccessor] = metrics;
const xColumn = columns.find(({ isBucketed, isSplit }) => isBucketed && !isSplit);
const yColumn = columns.find(({ isBucketed, isSplit }) => isBucketed && isSplit);
if (yColumn && !xColumn) {
return null;
}
const [xAccessor, yAccessor] = buckets;

const { params, uiState } = vis;
const state = uiState.get('vis', {}) ?? {};

Expand All @@ -55,8 +47,8 @@ export const getConfiguration = async (
isXAxisTitleVisible: true,
},
valueAccessor,
xAccessor: xColumn?.columnId,
yAccessor: yColumn?.columnId,
xAccessor,
yAccessor,
palette: palette ? { ...palette, accessor: valueAccessor } : undefined,
};
};
37 changes: 20 additions & 17 deletions src/plugins/vis_types/heatmap/public/convert_to_lens/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { HeatmapVisParams } from '../types';
const mockGetColumnsFromVis = jest.fn();
const mockGetConfiguration = jest.fn().mockReturnValue({});
const mockGetDataViewByIndexPatternId = jest.fn();
const mockConvertToFiltersColumn = jest.fn();

jest.mock('../services', () => ({
getDataViewsStart: jest.fn(() => ({ get: () => ({}), getDefault: () => ({}) })),
Expand All @@ -22,6 +23,7 @@ jest.mock('../services', () => ({
jest.mock('@kbn/visualizations-plugin/public', () => ({
convertToLensModule: Promise.resolve({
getColumnsFromVis: jest.fn(() => mockGetColumnsFromVis()),
convertToFiltersColumn: jest.fn(() => mockConvertToFiltersColumn()),
}),
getDataViewByIndexPatternId: jest.fn(() => mockGetDataViewByIndexPatternId()),
}));
Expand Down Expand Up @@ -58,6 +60,7 @@ const timefilter = {
describe('convertToLens', () => {
beforeEach(() => {
mockGetDataViewByIndexPatternId.mockReturnValue({ id: 'index-pattern' });
mockConvertToFiltersColumn.mockReturnValue({ columnId: 'column-id-1' });
});

afterEach(() => {
Expand Down Expand Up @@ -97,21 +100,7 @@ describe('convertToLens', () => {
expect(result).toBeNull();
});

test('should return null if getConfiguration returns null', async () => {
mockGetColumnsFromVis.mockReturnValue([
{
metrics: ['1'],
buckets: { all: ['2'] },
columns: [{ columnId: '2' }, { columnId: '1' }],
},
]);
mockGetConfiguration.mockReturnValue(Promise.resolve(null));
const result = await convertToLens(vis, timefilter);
expect(mockGetConfiguration).toBeCalledTimes(1);
expect(result).toBeNull();
});

test('should return null if no buckets are specified', async () => {
test('should return empty filters for x-axis if no buckets are specified', async () => {
mockGetColumnsFromVis.mockReturnValue([
{
metrics: ['1'],
Expand All @@ -120,12 +109,26 @@ describe('convertToLens', () => {
columnsWithoutReferenced: [
{ columnId: '1', meta: { aggId: 'agg-1' } },
{ columnId: '2', meta: { aggId: 'agg-2' } },
{ columnId: 'column-id-1' },
],
},
]);
const result = await convertToLens(vis, timefilter);
expect(mockGetColumnsFromVis).toBeCalledTimes(1);
expect(result).toBeNull();
expect(result).toEqual(
expect.objectContaining({
configuration: {},
indexPatternIds: ['index-pattern'],
layers: [
expect.objectContaining({
columnOrder: [],
columns: [{ columnId: '1', dataType: 'number' }, { columnId: 'column-id-1' }],
indexPatternId: 'index-pattern',
}),
],
type: 'lnsHeatmap',
})
);
});

test('should return correct state for valid vis', async () => {
Expand Down Expand Up @@ -154,7 +157,7 @@ describe('convertToLens', () => {
expect(result?.layers[0]).toEqual(
expect.objectContaining({
columnOrder: [],
columns: [{ columnId: '1', dataType: 'number' }],
columns: [{ columnId: '1', dataType: 'number' }, { columnId: 'column-id-1' }],
indexPatternId: 'index-pattern',
})
);
Expand Down
23 changes: 18 additions & 5 deletions src/plugins/vis_types/heatmap/public/convert_to_lens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const convertToLens: ConvertHeatmapToLensVisualization = async (vis, time
return null;
}

const { getColumnsFromVis } = await convertToLensModule;
const { getColumnsFromVis, convertToFiltersColumn } = await convertToLensModule;
const layers = getColumnsFromVis(vis, timefilter, dataView, {
buckets: ['segment'],
splits: ['group'],
Expand All @@ -56,17 +56,30 @@ export const convertToLens: ConvertHeatmapToLensVisualization = async (vis, time

const [layerConfig] = layers;

const xColumn = layerConfig.columns.find(({ isBucketed, isSplit }) => isBucketed && !isSplit);
const xAxisColumn =
xColumn ??
convertToFiltersColumn(uuid(), { filters: [{ input: { language: 'lucene', query: '*' } }] })!;

if (xColumn?.columnId !== xAxisColumn?.columnId) {
layerConfig.buckets.all.push(xAxisColumn.columnId);
layerConfig.columns.push(xAxisColumn);
}
const yColumn = layerConfig.columns.find(({ isBucketed, isSplit }) => isBucketed && isSplit);

if (!layerConfig.buckets.all.length || layerConfig.metrics.length > 1) {
return null;
}

const layerId = uuid();

const indexPatternId = dataView.id!;
const configuration = await getConfiguration(layerId, vis, layerConfig);
if (configuration === null) {
return null;
}
const configuration = await getConfiguration(layerId, vis, {
metrics: layerConfig.metrics,
buckets: [xAxisColumn.columnId, yColumn?.columnId].filter<string>((c): c is string =>
Boolean(c)
),
});

return {
type: 'lnsHeatmap',
Expand Down
1 change: 1 addition & 0 deletions src/plugins/visualizations/public/convert_to_lens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

export { getColumnsFromVis } from './schemas';
export {
convertToFiltersColumn,
getPercentageColumnFormulaColumn,
getPalette,
getPaletteFromStopsWithColors,
Expand Down
21 changes: 17 additions & 4 deletions x-pack/test/functional/apps/lens/open_in_lens/agg_based/heatmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
'timePicker',
'visEditor',
]);
const log = getService('log');

describe('Heatmap', function describeIndexTests() {
const isNewChartsLibraryEnabled = true;
Expand All @@ -31,8 +32,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await timePicker.setDefaultAbsoluteRange();
});

it('should not show the "Edit Visualization in Lens" menu item if no X-axis was specified', async () => {
expect(await visualize.hasNavigateToLensButton()).to.eql(false);
it('should show the "Edit Visualization in Lens" menu item if no X-axis was specified', async () => {
await visChart.waitForVisualizationRenderingStabilized();

expect(await visualize.hasNavigateToLensButton()).to.eql(true);
});

it('should show the "Edit Visualization in Lens" menu item', async () => {
Expand Down Expand Up @@ -82,13 +85,23 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
]);
});

it('should not convert to Lens if Y-axis is defined, but X-axis is not', async () => {
it('should convert to Lens if Y-axis is defined, but X-axis is not', async () => {
await visEditor.clickBucket('Y-axis');
await visEditor.selectAggregation('Terms');
await visEditor.selectField('machine.os.raw');
await visEditor.clickGo();

expect(await visualize.hasNavigateToLensButton()).to.eql(false);
await visualize.navigateToLensFromAnotherVisulization();
await lens.waitForVisualization('heatmapChart');
const debugState = await lens.getCurrentChartDebugState('heatmapChart');

if (!debugState) {
throw new Error('Debug state is not available');
}

expect(debugState.axes!.x[0].labels).to.eql(['*']);
expect(debugState.axes!.y[0].labels).to.eql(['win 8', 'win xp', 'win 7', 'ios', 'osx']);
expect(debugState.heatmap!.cells.length).to.eql(5);
});

it('should respect heatmap colors number', async () => {
Expand Down

0 comments on commit e975faa

Please sign in to comment.