Skip to content

Commit

Permalink
[Lens] Add date histogram interval to column name (#48271)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdavies authored Oct 16, 2019
1 parent fba41f6 commit 5023131
Show file tree
Hide file tree
Showing 17 changed files with 563 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { VisualizationContainer } from '../visualization_container';

export interface DatatableColumns {
columnIds: string[];
labels: string[];
}

interface Args {
Expand Down Expand Up @@ -95,11 +94,6 @@ export const datatableColumns: ExpressionFunction<
multi: true,
help: '',
},
labels: {
types: ['string'],
multi: true,
help: '',
},
},
fn: function fn(_context: unknown, args: DatatableColumns) {
return {
Expand Down Expand Up @@ -138,10 +132,11 @@ function DatatableComponent(props: DatatableProps & { formatFactory: FormatFacto
className="lnsDataTable"
data-test-subj="lnsDataTable"
columns={props.args.columns.columnIds
.map((field, index) => {
.map(field => {
const col = firstTable.columns.find(c => c.id === field);
return {
field,
name: props.args.columns.labels[index],
name: (col && col.name) || '',
};
})
.filter(({ field }) => !!field)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,6 @@ export const datatableVisualization: Visualization<
function: 'lens_datatable_columns',
arguments: {
columnIds: operations.map(o => o.columnId),
labels: operations.map(
o =>
o.operation.label ||
i18n.translate('xpack.lens.datatable.na', {
defaultMessage: 'N/A',
})
),
},
},
],
Expand Down
86 changes: 86 additions & 0 deletions x-pack/legacy/plugins/lens/public/indexpattern_plugin/auto_date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { TimeBuckets } from 'ui/time_buckets';
import dateMath from '@elastic/datemath';
import {
ExpressionFunction,
KibanaContext,
} from '../../../../../../src/plugins/expressions/common';

interface LensAutoDateProps {
aggConfigs: string;
}

export function getAutoInterval(ctx?: KibanaContext | null) {
if (!ctx || !ctx.timeRange) {
return;
}

const { timeRange } = ctx;
const buckets = new TimeBuckets();
buckets.setInterval('auto');
buckets.setBounds({
min: dateMath.parse(timeRange.from),
max: dateMath.parse(timeRange.to, { roundUp: true }),
});

return buckets.getInterval();
}

/**
* Convert all 'auto' date histograms into a concrete value (e.g. 2h).
* This allows us to support 'auto' on all date fields, and opens the
* door to future customizations (e.g. adjusting the level of detail, etc).
*/
export const autoDate: ExpressionFunction<
'lens_auto_date',
KibanaContext | null,
LensAutoDateProps,
string
> = {
name: 'lens_auto_date',
aliases: [],
help: '',
context: {
types: ['kibana_context', 'null'],
},
args: {
aggConfigs: {
types: ['string'],
default: '""',
help: '',
},
},
fn(ctx: KibanaContext, args: LensAutoDateProps) {
const interval = getAutoInterval(ctx);

if (!interval) {
return args.aggConfigs;
}

const configs = JSON.parse(args.aggConfigs) as Array<{
type: string;
params: { interval: string };
}>;

const updatedConfigs = configs.map(c => {
if (c.type !== 'date_histogram' || !c.params || c.params.interval !== 'auto') {
return c;
}

return {
...c,
params: {
...c.params,
interval: interval.expression,
},
};
});

return JSON.stringify(updatedConfigs);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe('IndexPattern Data Source', () => {
metricsAtAllLevels=false
partialRows=false
includeFormatHints=true
aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1d\\",\\"drop_partials\\":false,\\"min_doc_count\\":0,\\"extended_bounds\\":{}}}]' | lens_rename_columns idMap='{\\"col-0-col1\\":\\"col1\\",\\"col-1-col2\\":\\"col2\\"}'"
aggConfigs={lens_auto_date aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1d\\",\\"drop_partials\\":false,\\"min_doc_count\\":0,\\"extended_bounds\\":{}}}]'} | lens_rename_columns idMap='{\\"col-0-col1\\":{\\"label\\":\\"Count of Documents\\",\\"dataType\\":\\"number\\",\\"isBucketed\\":false,\\"operationType\\":\\"count\\",\\"id\\":\\"col1\\"},\\"col-1-col2\\":{\\"label\\":\\"Date\\",\\"dataType\\":\\"date\\",\\"isBucketed\\":true,\\"operationType\\":\\"date_histogram\\",\\"sourceField\\":\\"timestamp\\",\\"params\\":{\\"interval\\":\\"1d\\"},\\"id\\":\\"col2\\"}}'"
`);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ describe('IndexPattern Data Source suggestions', () => {
{
columnId: 'id1',
operation: {
label: 'Date histogram of timestamp',
label: 'timestamp',
dataType: 'date',
isBucketed: true,
scale: 'interval',
Expand Down Expand Up @@ -1132,7 +1132,7 @@ describe('IndexPattern Data Source suggestions', () => {
{
columnId: 'id1',
operation: {
label: 'Date histogram of timestamp',
label: 'timestamp',
dataType: 'date',
isBucketed: true,
scale: 'interval',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('date_histogram', () => {
expect(column.params.interval).toEqual('auto');
});

it('should create column object with manual interval for non-primary time fields', () => {
it('should create column object with auto interval for non-primary time fields', () => {
const column = dateHistogramOperation.buildColumn({
columns: {},
suggestedPriority: 0,
Expand All @@ -150,7 +150,7 @@ describe('date_histogram', () => {
searchable: true,
},
});
expect(column.params.interval).toEqual('d');
expect(column.params.interval).toEqual('auto');
});

it('should create column object with restrictions', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ const FixedEuiRange = (EuiRange as unknown) as React.ComponentType<
}
>;

function ofName(name: string) {
return i18n.translate('xpack.lens.indexPattern.dateHistogramOf', {
defaultMessage: 'Date histogram of {name}',
values: { name },
});
}

function supportsAutoInterval(fieldName: string, indexPattern: IndexPattern): boolean {
return indexPattern.timeFieldName ? indexPattern.timeFieldName === fieldName : false;
}
Expand Down Expand Up @@ -67,15 +60,15 @@ export const dateHistogramOperation: OperationDefinition<DateHistogramIndexPatte
}
},
buildColumn({ suggestedPriority, field, indexPattern }) {
let interval = indexPattern.timeFieldName === field.name ? autoInterval : defaultCustomInterval;
let interval = autoInterval;
let timeZone: string | undefined;
if (field.aggregationRestrictions && field.aggregationRestrictions.date_histogram) {
interval = (field.aggregationRestrictions.date_histogram.calendar_interval ||
field.aggregationRestrictions.date_histogram.fixed_interval) as string;
timeZone = field.aggregationRestrictions.date_histogram.time_zone;
}
return {
label: ofName(field.name),
label: field.name,
dataType: 'date',
operationType: 'date_histogram',
suggestedPriority,
Expand Down Expand Up @@ -136,7 +129,7 @@ export const dateHistogramOperation: OperationDefinition<DateHistogramIndexPatte
onFieldChange: (oldColumn, indexPattern, field) => {
return {
...oldColumn,
label: ofName(field.name),
label: field.name,
sourceField: field.name,
params: {
...oldColumn.params,
Expand Down Expand Up @@ -172,8 +165,6 @@ export const dateHistogramOperation: OperationDefinition<DateHistogramIndexPatte
);
const intervalIsRestricted =
field!.aggregationRestrictions && field!.aggregationRestrictions.date_histogram;
const fieldAllowsAutoInterval =
state.indexPatterns[state.layers[layerId].indexPatternId].timeFieldName === field!.name;

function intervalToNumeric(interval: string) {
return supportedIntervals.indexOf(interval);
Expand All @@ -192,7 +183,7 @@ export const dateHistogramOperation: OperationDefinition<DateHistogramIndexPatte

return (
<EuiForm>
{fieldAllowsAutoInterval && (
{!intervalIsRestricted && (
<EuiFormRow>
<EuiSwitch
label={i18n.translate('xpack.lens.indexPattern.dateHistogram.autoInterval', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ExpressionFunction } from '../../../../../../src/legacy/core_plugins/in
import { functionsRegistry } from '../../../../../../src/legacy/core_plugins/interpreter/public/registries';
import { getIndexPatternDatasource } from './indexpattern';
import { renameColumns } from './rename_columns';
import { autoDate } from './auto_date';

// TODO these are intermediary types because interpreter is not typed yet
// They can get replaced by references to the real interfaces as soon as they
Expand All @@ -36,6 +37,7 @@ class IndexPatternDatasourcePlugin {

setup(core: CoreSetup, { interpreter }: IndexPatternDatasourceSetupPlugins) {
interpreter.functionsRegistry.register(() => renameColumns);
interpreter.functionsRegistry.register(() => autoDate);
}

stop() {}
Expand Down
Loading

0 comments on commit 5023131

Please sign in to comment.