Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Add previous time shift back #121284

Merged
merged 12 commits into from
Jan 12, 2022
3 changes: 3 additions & 0 deletions docs/user/dashboard/lens-advanced.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ image::images/lens_time_shift.png[Line chart with week-over-week sales compariso

. Click *Save and return*.

Time shifts can be used on any metric. The special shift *previous* will show the time window preceding the currently selected one in the time picker in the top right, spanning the same duration.
For example, if *Last 7 days* is selected in the time picker, *previous* will show data from 14 days ago to 7 days ago. This mode can't be used together with date histograms.

[float]
[[compare-time-as-percent]]
==== Analyze the percent change between time ranges
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ export function TimeShift({
return null;
}

const { isValueTooSmall, isValueNotMultiple, canShift } = getLayerTimeShiftChecks(
getDateHistogramInterval(layer, indexPattern, activeData, layerId)
);
const dateHistogramInterval = getDateHistogramInterval(layer, indexPattern, activeData, layerId);
const { isValueTooSmall, isValueNotMultiple, canShift } =
getLayerTimeShiftChecks(dateHistogramInterval);

if (!canShift) {
return null;
Expand Down Expand Up @@ -167,7 +167,10 @@ export function TimeShift({
options={timeShiftOptions.filter(({ value }) => {
const parsedValue = parseTimeShift(value);
return (
parsedValue && !isValueTooSmall(parsedValue) && !isValueNotMultiple(parsedValue)
parsedValue &&
!isValueTooSmall(parsedValue) &&
!isValueNotMultiple(parsedValue) &&
!(parsedValue === 'previous' && dateHistogramInterval.interval)
);
})}
selectedOptions={getSelectedOption()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
} from './utils';
import { DEFAULT_TIME_SCALE } from '../../time_scale_utils';
import { OperationDefinition } from '..';
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';

const ofName = buildLabelFunction((name?: string) => {
return i18n.translate('xpack.lens.indexPattern.CounterRateOf', {
Expand Down Expand Up @@ -104,13 +105,16 @@ export const counterRateOperation: OperationDefinition<
return hasDateField(newIndexPattern);
},
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
return getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.counterRate', {
defaultMessage: 'Counter rate',
})
);
return combineErrorMessages([
getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.counterRate', {
defaultMessage: 'Counter rate',
})
),
getDisallowedPreviousShiftMessage(layer, columnId),
]);
},
getDisabledStatus(indexPattern, layer, layerType) {
const opName = i18n.translate('xpack.lens.indexPattern.counterRate', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
checkForDataLayerType,
} from './utils';
import { OperationDefinition } from '..';
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';

const ofName = buildLabelFunction((name?: string) => {
return i18n.translate('xpack.lens.indexPattern.cumulativeSumOf', {
Expand Down Expand Up @@ -101,13 +102,16 @@ export const cumulativeSumOperation: OperationDefinition<
return true;
},
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
return getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
defaultMessage: 'Cumulative sum',
})
);
return combineErrorMessages([
getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
defaultMessage: 'Cumulative sum',
})
),
getDisallowedPreviousShiftMessage(layer, columnId),
]);
},
getDisabledStatus(indexPattern, layer, layerType) {
const opName = i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
} from './utils';
import { adjustTimeScaleOnOtherColumnChange } from '../../time_scale_utils';
import { OperationDefinition } from '..';
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';

const OPERATION_NAME = 'differences';

Expand Down Expand Up @@ -92,13 +93,16 @@ export const derivativeOperation: OperationDefinition<
},
onOtherColumnChanged: adjustTimeScaleOnOtherColumnChange,
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
return getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.derivative', {
defaultMessage: 'Differences',
})
);
return combineErrorMessages([
getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.derivative', {
defaultMessage: 'Differences',
})
),
getDisallowedPreviousShiftMessage(layer, columnId),
]);
},
getDisabledStatus(indexPattern, layer, layerType) {
const opName = i18n.translate('xpack.lens.indexPattern.derivative', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ import {
checkForDataLayerType,
} from './utils';
import { updateColumnParam } from '../../layer_helpers';
import { getFormatFromPreviousColumn, isValidNumber, getFilter } from '../helpers';
import {
getFormatFromPreviousColumn,
isValidNumber,
getFilter,
combineErrorMessages,
} from '../helpers';
import { adjustTimeScaleOnOtherColumnChange } from '../../time_scale_utils';
import { HelpPopover, HelpPopoverButton } from '../../../help_popover';
import type { OperationDefinition, ParamEditorProps } from '..';
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';

const ofName = buildLabelFunction((name?: string) => {
return i18n.translate('xpack.lens.indexPattern.movingAverageOf', {
Expand Down Expand Up @@ -114,13 +120,16 @@ export const movingAverageOperation: OperationDefinition<
},
onOtherColumnChanged: adjustTimeScaleOnOtherColumnChange,
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
return getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.movingAverage', {
defaultMessage: 'Moving average',
})
);
return combineErrorMessages([
getErrorsForDateReference(
layer,
columnId,
i18n.translate('xpack.lens.indexPattern.movingAverage', {
defaultMessage: 'Moving average',
})
),
getDisallowedPreviousShiftMessage(layer, columnId),
]);
},
getHelpMessage: () => <MovingAveragePopup />,
getDisabledStatus(indexPattern, layer, layerType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import {
getInvalidFieldMessage,
getSafeName,
getFilter,
combineErrorMessages,
} from './helpers';
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';

const supportedTypes = new Set([
'string',
Expand Down Expand Up @@ -71,7 +73,10 @@ export const cardinalityOperation: OperationDefinition<CardinalityIndexPatternCo
}
},
getErrorMessage: (layer, columnId, indexPattern) =>
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
combineErrorMessages([
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
getDisallowedPreviousShiftMessage(layer, columnId),
]),
isTransferable: (column, newIndexPattern) => {
const newField = newIndexPattern.getFieldByName(column.sourceField);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import { buildExpressionFunction } from '../../../../../../../src/plugins/expres
import { OperationDefinition } from './index';
import { FormattedIndexPatternColumn, FieldBasedIndexPatternColumn } from './column_types';
import { IndexPatternField } from '../../types';
import { getInvalidFieldMessage, getFilter, isColumnFormatted } from './helpers';
import {
getInvalidFieldMessage,
getFilter,
isColumnFormatted,
combineErrorMessages,
} from './helpers';
import {
adjustTimeScaleLabelSuffix,
adjustTimeScaleOnOtherColumnChange,
} from '../time_scale_utils';
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';

const countLabel = i18n.translate('xpack.lens.indexPattern.countOf', {
defaultMessage: 'Count of records',
Expand All @@ -34,7 +40,10 @@ export const countOperation: OperationDefinition<CountIndexPatternColumn, 'field
}),
input: 'field',
getErrorMessage: (layer, columnId, indexPattern) =>
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
combineErrorMessages([
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
getDisallowedPreviousShiftMessage(layer, columnId),
]),
onFieldChange: (oldColumn, field) => {
return {
...oldColumn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,9 @@ export async function getNamedArgumentSuggestions({
if (typeof dateHistogramInterval === 'undefined') return true;
const parsedValue = parseTimeShift(value);
return (
typeof parsedValue === 'string' ||
Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval)
parsedValue !== 'previous' &&
(parsedValue === 'invalid' ||
Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval))
);
})
.map(({ value }) => value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ export function getInvalidFieldMessage(
return undefined;
}

export function combineErrorMessages(
errorMessages: Array<string[] | undefined>
): string[] | undefined {
const messages = (errorMessages.filter(Boolean) as string[][]).flat();
return messages.length ? messages : undefined;
}

export function getSafeName(name: string, indexPattern: IndexPattern): string {
const field = indexPattern.getFieldByName(name);
return field
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
getFilter,
} from './helpers';
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';

function ofName(name: string, timeShift: string | undefined) {
return adjustTimeScaleLabelSuffix(
Expand Down Expand Up @@ -152,6 +153,7 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
if (invalidSortFieldMessage) {
errorMessages = [invalidSortFieldMessage];
}
errorMessages.push(...(getDisallowedPreviousShiftMessage(layer, columnId) || []));
return errorMessages.length ? errorMessages : undefined;
},
buildColumn({ field, previousColumn, indexPattern }, columnParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getInvalidFieldMessage,
getSafeName,
getFilter,
combineErrorMessages,
} from './helpers';
import {
FormattedIndexPatternColumn,
Expand All @@ -23,6 +24,7 @@ import {
adjustTimeScaleLabelSuffix,
adjustTimeScaleOnOtherColumnChange,
} from '../time_scale_utils';
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';

type MetricColumn<T> = FormattedIndexPatternColumn &
FieldBasedIndexPatternColumn & {
Expand Down Expand Up @@ -132,7 +134,13 @@ function buildMetricOperation<T extends MetricColumn<string>>({
}).toAst();
},
getErrorMessage: (layer, columnId, indexPattern) =>
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
combineErrorMessages([
getInvalidFieldMessage(
layer.columns[columnId] as FieldBasedIndexPatternColumn,
indexPattern
),
getDisallowedPreviousShiftMessage(layer, columnId),
]),
filterable: true,
documentation: {
section: 'elasticsearch',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import {
isValidNumber,
getFilter,
isColumnOfType,
combineErrorMessages,
} from './helpers';
import { FieldBasedIndexPatternColumn } from './column_types';
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
import { useDebouncedValue } from '../../../shared_components';
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';

export interface PercentileIndexPatternColumn extends FieldBasedIndexPatternColumn {
operationType: 'percentile';
Expand Down Expand Up @@ -142,7 +144,10 @@ export const percentileOperation: OperationDefinition<
).toAst();
},
getErrorMessage: (layer, columnId, indexPattern) =>
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
combineErrorMessages([
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
getDisallowedPreviousShiftMessage(layer, columnId),
]),
paramEditor: function PercentileParamEditor({
layer,
updateLayer,
Expand Down
Loading