Skip to content

Commit

Permalink
[Lens] Auto date histogram (#43775)
Browse files Browse the repository at this point in the history
* Add auto date histogram

* Improve documentation and cleanup

* Add tests

* Change test name
  • Loading branch information
Tim Roes authored Aug 23, 2019
1 parent db9bce7 commit c7fae6c
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,123 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { createMockedIndexPattern, createMockedRestrictedIndexPattern } from '../mocks';

export function getIndexPatterns() {
return new Promise(resolve => {
resolve([
{
id: '1',
title: 'my-fake-index-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'start_date',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'memory',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
{
name: 'dest',
type: 'string',
aggregatable: true,
searchable: true,
},
],
},
{
id: '2',
title: 'my-fake-restricted-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
],
typeMeta: {
params: {
rollup_index: 'my-fake-index-pattern',
},
aggs: {
terms: {
source: {
agg: 'terms',
},
},
date_histogram: {
timestamp: {
agg: 'date_histogram',
fixed_interval: '1d',
delay: '7d',
time_zone: 'UTC',
},
},
histogram: {
bytes: {
agg: 'histogram',
interval: 1000,
},
},
avg: {
bytes: {
agg: 'avg',
},
},
max: {
bytes: {
agg: 'max',
},
},
min: {
bytes: {
agg: 'min',
},
},
sum: {
bytes: {
agg: 'sum',
},
},
},
},
},
]);
resolve([createMockedIndexPattern(), createMockedRestrictedIndexPattern()]);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import {
OperationType,
} from '../indexpattern';

import { getAvailableOperationsByMetadata, buildColumn } from '../operations';
import {
getAvailableOperationsByMetadata,
buildColumn,
operationDefinitionMap,
OperationDefinition,
} from '../operations';
import { PopoverEditor } from './popover_editor';
import { DragContextState, ChildDragDropProvider, DragDrop } from '../../drag_drop';
import { changeColumn, deleteColumn } from '../state_helpers';
import { isDraggedField } from '../utils';
import { isDraggedField, hasField } from '../utils';

export type IndexPatternDimensionPanelProps = DatasourceDimensionPanelProps & {
state: IndexPatternPrivateState;
Expand Down Expand Up @@ -109,18 +114,42 @@ export const IndexPatternDimensionPanel = memo(function IndexPatternDimensionPan
return;
}

props.setState(
changeColumn({
state: props.state,
layerId,
columnId: props.columnId,
newColumn: buildColumn({
const operationsForNewField =
operationFieldSupportMatrix.operationByField[droppedItem.field.name];

// We need to check if dragging in a new field, was just a field change on the same
// index pattern and on the same operations (therefore checking if the new field supports
// our previous operation)
const hasFieldChanged =
selectedColumn &&
hasField(selectedColumn) &&
selectedColumn.sourceField !== droppedItem.field.name &&
operationsForNewField &&
operationsForNewField.includes(selectedColumn.operationType);

// If only the field has changed use the onFieldChange method on the operation to get the
// new column, otherwise use the regular buildColumn to get a new column.
const newColumn = hasFieldChanged
? (operationDefinitionMap[selectedColumn.operationType] as OperationDefinition<
IndexPatternColumn
>).onFieldChange(selectedColumn, currentIndexPattern, droppedItem.field)
: buildColumn({
columns: props.state.layers[props.layerId].columns,
indexPattern: currentIndexPattern,
layerId,
suggestedPriority: props.suggestedPriority,
field: droppedItem.field,
}),
});

props.setState(
changeColumn({
state: props.state,
layerId,
columnId: props.columnId,
newColumn,
// If the field has changed, the onFieldChange method needs to take care of everything including moving
// over params. If we create a new column above we want changeColumn to move over params.
keepParams: !hasFieldChanged,
})
);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ import {
IndexPatternField,
} from '../indexpattern';
import { IndexPatternDimensionPanelProps, OperationFieldSupportMatrix } from './dimension_panel';
import { operationDefinitionMap, getOperationDisplay, buildColumn } from '../operations';
import {
operationDefinitionMap,
getOperationDisplay,
buildColumn,
OperationDefinition,
} from '../operations';
import { deleteColumn, changeColumn } from '../state_helpers';
import { FieldSelect } from './field_select';
import { hasField } from '../utils';
Expand Down Expand Up @@ -271,24 +276,44 @@ export function PopoverEditor(props: PopoverEditorProps) {
);
}}
onChoose={choice => {
const column = buildColumn({
columns: props.state.layers[props.layerId].columns,
field: 'field' in choice ? fieldMap[choice.field] : undefined,
indexPattern: currentIndexPattern,
layerId: props.layerId,
suggestedPriority: props.suggestedPriority,
op:
incompatibleSelectedOperationType ||
('field' in choice ? choice.operationType : undefined),
asDocumentOperation: choice.type === 'document',
});
let column: IndexPatternColumn;
if (
!incompatibleSelectedOperationType &&
selectedColumn &&
('field' in choice && choice.operationType === selectedColumn.operationType)
) {
// If we just changed the field are not in an error state and the operation didn't change,
// we use the operations onFieldChange method to calculate the new column.
const operation = operationDefinitionMap[
choice.operationType
] as OperationDefinition<IndexPatternColumn>;
column = operation.onFieldChange(
selectedColumn,
currentIndexPattern,
fieldMap[choice.field]
);
} else {
// Otherwise we'll use the buildColumn method to calculate a new column
column = buildColumn({
columns: props.state.layers[props.layerId].columns,
field: 'field' in choice ? fieldMap[choice.field] : undefined,
indexPattern: currentIndexPattern,
layerId: props.layerId,
suggestedPriority: props.suggestedPriority,
op:
incompatibleSelectedOperationType ||
('field' in choice ? choice.operationType : undefined),
asDocumentOperation: choice.type === 'document',
});
}

setState(
changeColumn({
state,
layerId,
columnId,
newColumn: column,
keepParams: false,
})
);
setInvalidOperationType(null);
Expand Down
117 changes: 117 additions & 0 deletions x-pack/legacy/plugins/lens/public/indexpattern_plugin/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,123 @@
*/

import { DragContextState } from '../drag_drop';
import { IndexPattern } from './indexpattern';

export const createMockedIndexPattern = (): IndexPattern => ({
id: '1',
title: 'my-fake-index-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'start_date',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'memory',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
{
name: 'dest',
type: 'string',
aggregatable: true,
searchable: true,
},
],
});

export const createMockedRestrictedIndexPattern = () => ({
id: '2',
title: 'my-fake-restricted-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
],
typeMeta: {
params: {
rollup_index: 'my-fake-index-pattern',
},
aggs: {
terms: {
source: {
agg: 'terms',
},
},
date_histogram: {
timestamp: {
agg: 'date_histogram',
fixed_interval: '1d',
delay: '7d',
time_zone: 'UTC',
},
},
histogram: {
bytes: {
agg: 'histogram',
interval: 1000,
},
},
avg: {
bytes: {
agg: 'avg',
},
},
max: {
bytes: {
agg: 'max',
},
},
min: {
bytes: {
agg: 'min',
},
},
sum: {
bytes: {
agg: 'sum',
},
},
},
},
});

export function createMockedDragDropContext(): jest.Mocked<DragContextState> {
return {
Expand Down
Loading

0 comments on commit c7fae6c

Please sign in to comment.