[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:
Wylie Conlon 2020-04-30 10:52:10 -04:00 committed by GitHub
parent 793d6f5689
commit 988b93edca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 158 additions and 11 deletions

View file

@ -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,
},
];
},

View file

@ -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',
}),
})
);
});
});
});

View file

@ -486,7 +486,7 @@ function createChangedNestingSuggestion(state: IndexPatternPrivateState, layerId
layerId,
updatedLayer,
label: getNestedTitle([layer.columns[secondBucket], layer.columns[firstBucket]]),
changeType: 'extended',
changeType: 'reorder',
});
}

View file

@ -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;

View file

@ -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 = {

View file

@ -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),
};