[Lens] Hide some suggestions in preparation for pie charts (#64740)
* [Lens] Hide some suggestions in preparation for pie charts * Suggest reordering the X and Break down by axis * More tweaks
This commit is contained in:
parent
793d6f5689
commit
988b93edca
|
@ -126,8 +126,8 @@ export const datatableVisualization: Visualization<
|
|||
],
|
||||
},
|
||||
previewIcon: chartTableSVG,
|
||||
// dont show suggestions for reduced versions or single-line tables
|
||||
hide: table.changeType === 'reduced' || !table.isMultiRow,
|
||||
// tables are hidden from suggestion bar, but used for drag & drop and chart switching
|
||||
hide: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
|
@ -1552,6 +1552,62 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
expect(suggestions[0].table.columns.length).toBe(1);
|
||||
expect(suggestions[0].table.columns[0].operation.label).toBe('Sum of field1');
|
||||
});
|
||||
|
||||
it('contains a reordering suggestion when there are exactly 2 buckets', () => {
|
||||
const initialState = testInitialState();
|
||||
const state: IndexPatternPrivateState = {
|
||||
indexPatternRefs: [],
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
indexPatterns: expectedIndexPatterns,
|
||||
showEmptyFields: true,
|
||||
layers: {
|
||||
first: {
|
||||
...initialState.layers.first,
|
||||
columns: {
|
||||
id1: {
|
||||
label: 'Date histogram',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
operationType: 'date_histogram',
|
||||
sourceField: 'field2',
|
||||
params: {
|
||||
interval: 'd',
|
||||
},
|
||||
},
|
||||
id2: {
|
||||
label: 'Top 5',
|
||||
dataType: 'string',
|
||||
isBucketed: true,
|
||||
|
||||
operationType: 'terms',
|
||||
sourceField: 'field1',
|
||||
params: { size: 5, orderBy: { type: 'alphabetical' }, orderDirection: 'asc' },
|
||||
},
|
||||
id3: {
|
||||
label: 'Average of field1',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
|
||||
operationType: 'avg',
|
||||
sourceField: 'field1',
|
||||
},
|
||||
},
|
||||
columnOrder: ['id1', 'id2', 'id3'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const suggestions = getDatasourceSuggestionsFromCurrentState(state);
|
||||
expect(suggestions).toContainEqual(
|
||||
expect.objectContaining({
|
||||
table: expect.objectContaining({
|
||||
changeType: 'reorder',
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -486,7 +486,7 @@ function createChangedNestingSuggestion(state: IndexPatternPrivateState, layerId
|
|||
layerId,
|
||||
updatedLayer,
|
||||
label: getNestedTitle([layer.columns[secondBucket], layer.columns[firstBucket]]),
|
||||
changeType: 'extended',
|
||||
changeType: 'reorder',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -103,9 +103,16 @@ export interface TableSuggestion {
|
|||
* * `unchanged` means the table is the same in the currently active configuration
|
||||
* * `reduced` means the table is a reduced version of the currently active table (some columns dropped, but not all of them)
|
||||
* * `extended` means the table is an extended version of the currently active table (added one or multiple additional columns)
|
||||
* * `reorder` means the table columns have changed order, which change the data as well
|
||||
* * `layers` means the change is a change to the layer structure, not to the table
|
||||
*/
|
||||
export type TableChangeType = 'initial' | 'unchanged' | 'reduced' | 'extended' | 'layers';
|
||||
export type TableChangeType =
|
||||
| 'initial'
|
||||
| 'unchanged'
|
||||
| 'reduced'
|
||||
| 'extended'
|
||||
| 'reorder'
|
||||
| 'layers';
|
||||
|
||||
export interface DatasourceSuggestion<T = unknown> {
|
||||
state: T;
|
||||
|
|
|
@ -186,7 +186,7 @@ describe('xy_suggestions', () => {
|
|||
isMultiRow: true,
|
||||
columns: [numCol('price'), numCol('quantity'), dateCol('date'), strCol('product')],
|
||||
layerId: 'first',
|
||||
changeType: 'unchanged',
|
||||
changeType: 'extended',
|
||||
label: 'Datasource title',
|
||||
},
|
||||
keptLayerIds: [],
|
||||
|
@ -196,6 +196,34 @@ describe('xy_suggestions', () => {
|
|||
expect(suggestion.title).toEqual('Datasource title');
|
||||
});
|
||||
|
||||
test('suggests only stacked bar chart when xy chart is inactive', () => {
|
||||
const [suggestion, ...rest] = getSuggestions({
|
||||
table: {
|
||||
isMultiRow: true,
|
||||
columns: [dateCol('date'), numCol('price')],
|
||||
layerId: 'first',
|
||||
changeType: 'unchanged',
|
||||
label: 'Datasource title',
|
||||
},
|
||||
keptLayerIds: [],
|
||||
});
|
||||
|
||||
expect(rest).toHaveLength(0);
|
||||
expect(suggestion.title).toEqual('Bar chart');
|
||||
expect(suggestion.state).toEqual(
|
||||
expect.objectContaining({
|
||||
layers: [
|
||||
expect.objectContaining({
|
||||
seriesType: 'bar_stacked',
|
||||
xAccessor: 'date',
|
||||
accessors: ['price'],
|
||||
splitAccessor: undefined,
|
||||
}),
|
||||
],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('hides reduced suggestions if there is a current state', () => {
|
||||
const [suggestion, ...rest] = getSuggestions({
|
||||
table: {
|
||||
|
@ -224,7 +252,7 @@ describe('xy_suggestions', () => {
|
|||
expect(suggestion.hide).toBeTruthy();
|
||||
});
|
||||
|
||||
test('does not hide reduced suggestions if xy visualization is not active', () => {
|
||||
test('hides reduced suggestions if xy visualization is not active', () => {
|
||||
const [suggestion, ...rest] = getSuggestions({
|
||||
table: {
|
||||
isMultiRow: true,
|
||||
|
@ -236,7 +264,7 @@ describe('xy_suggestions', () => {
|
|||
});
|
||||
|
||||
expect(rest).toHaveLength(0);
|
||||
expect(suggestion.hide).toBeFalsy();
|
||||
expect(suggestion.hide).toBeTruthy();
|
||||
});
|
||||
|
||||
test('only makes a seriesType suggestion for unchanged table without split', () => {
|
||||
|
@ -419,6 +447,44 @@ describe('xy_suggestions', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('changes column mappings when suggestion is reorder', () => {
|
||||
const currentState: XYState = {
|
||||
legend: { isVisible: true, position: 'bottom' },
|
||||
preferredSeriesType: 'bar',
|
||||
layers: [
|
||||
{
|
||||
accessors: ['price'],
|
||||
layerId: 'first',
|
||||
seriesType: 'bar',
|
||||
splitAccessor: 'category',
|
||||
xAccessor: 'product',
|
||||
},
|
||||
],
|
||||
};
|
||||
const [suggestion, ...rest] = getSuggestions({
|
||||
table: {
|
||||
isMultiRow: true,
|
||||
columns: [strCol('category'), strCol('product'), numCol('price')],
|
||||
layerId: 'first',
|
||||
changeType: 'reorder',
|
||||
},
|
||||
state: currentState,
|
||||
keptLayerIds: [],
|
||||
});
|
||||
|
||||
expect(rest).toHaveLength(0);
|
||||
expect(suggestion.state).toEqual({
|
||||
...currentState,
|
||||
layers: [
|
||||
{
|
||||
...currentState.layers[0],
|
||||
xAccessor: 'category',
|
||||
splitAccessor: 'product',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('overwrites column to dimension mappings if a date dimension is added', () => {
|
||||
(generateId as jest.Mock).mockReturnValueOnce('dummyCol');
|
||||
const currentState: XYState = {
|
||||
|
|
|
@ -99,11 +99,14 @@ function getBucketMappings(table: TableSuggestion, currentState?: State) {
|
|||
// reverse the buckets before prioritization to always use the most inner
|
||||
// bucket of the highest-prioritized group as x value (don't use nested
|
||||
// buckets as split series)
|
||||
const prioritizedBuckets = prioritizeColumns(buckets.reverse());
|
||||
const prioritizedBuckets = prioritizeColumns([...buckets].reverse());
|
||||
|
||||
if (!currentLayer || table.changeType === 'initial') {
|
||||
return prioritizedBuckets;
|
||||
}
|
||||
if (table.changeType === 'reorder') {
|
||||
return buckets;
|
||||
}
|
||||
|
||||
// if existing table is just modified, try to map buckets to the current dimensions
|
||||
const currentXColumnIndex = prioritizedBuckets.findIndex(
|
||||
|
@ -175,12 +178,24 @@ function getSuggestionsForLayer({
|
|||
keptLayerIds,
|
||||
};
|
||||
|
||||
const isSameState = currentState && changeType === 'unchanged';
|
||||
// handles the simplest cases, acting as a chart switcher
|
||||
if (!currentState && changeType === 'unchanged') {
|
||||
return [
|
||||
{
|
||||
...buildSuggestion(options),
|
||||
title: i18n.translate('xpack.lens.xySuggestions.barChartTitle', {
|
||||
defaultMessage: 'Bar chart',
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const isSameState = currentState && changeType === 'unchanged';
|
||||
if (!isSameState) {
|
||||
return buildSuggestion(options);
|
||||
}
|
||||
|
||||
// Suggestions are either changing the data, or changing the way the data is used
|
||||
const sameStateSuggestions: Array<VisualizationSuggestion<State>> = [];
|
||||
|
||||
// if current state is using the same data, suggest same chart with different presentational configuration
|
||||
|
@ -374,8 +389,11 @@ function buildSuggestion({
|
|||
return {
|
||||
title,
|
||||
score: getScore(yValues, splitBy, changeType),
|
||||
// don't advertise chart of same type but with less data
|
||||
hide: currentState && changeType === 'reduced',
|
||||
hide:
|
||||
// Only advertise very clear changes when XY chart is not active
|
||||
(!currentState && changeType !== 'unchanged' && changeType !== 'extended') ||
|
||||
// Don't advertise removing dimensions
|
||||
(currentState && changeType === 'reduced'),
|
||||
state,
|
||||
previewIcon: getIconForSeries(seriesType),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue