Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/user/dashboard/tsvb.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ The index pattern mode unlocks many new features, such as:

* Interactive filters for time series visualizations

* Custom field formats

* Better performance

[float]
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/vis_type_timeseries/common/agg_utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('agg utils', () => {
isFieldRequired: true,
isFilterRatioSupported: false,
isHistogramSupported: false,
isFieldFormattingDisabled: false,
hasExtendedStats: true,
};
const expected = [
Expand Down Expand Up @@ -95,6 +96,7 @@ describe('agg utils', () => {
isFieldRequired: false,
isFilterRatioSupported: false,
isHistogramSupported: false,
isFieldFormattingDisabled: false,
hasExtendedStats: false,
};
const expected = [
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/vis_type_timeseries/common/agg_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface Agg {
isFieldRequired: boolean;
isFilterRatioSupported: boolean;
isHistogramSupported: boolean;
isFieldFormattingDisabled: boolean;
hasExtendedStats: boolean;
};
}
Expand All @@ -37,6 +38,7 @@ const aggDefaultMeta = {
isFieldRequired: true,
isFilterRatioSupported: false,
isHistogramSupported: false,
isFieldFormattingDisabled: false,
hasExtendedStats: false,
};

Expand Down Expand Up @@ -201,6 +203,7 @@ export const aggs: Agg[] = [
id: TSVB_METRIC_TYPES.CALCULATION,
meta: {
...aggDefaultMeta,
isFieldFormattingDisabled: true,
type: AGG_TYPE.PARENT_PIPELINE,
label: i18n.translate('visTypeTimeseries.aggUtils.bucketScriptLabel', {
defaultMessage: 'Bucket Script',
Expand Down Expand Up @@ -342,6 +345,7 @@ export const aggs: Agg[] = [
id: TSVB_METRIC_TYPES.MATH,
meta: {
...aggDefaultMeta,
isFieldFormattingDisabled: true,
type: AGG_TYPE.SPECIAL,
label: i18n.translate('visTypeTimeseries.aggUtils.mathLabel', { defaultMessage: 'Math' }),
},
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/vis_type_timeseries/common/calculate_label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const calculateLabel = (

if (includes(paths, metric.type)) {
const targetMetric = metrics.find((m) => startsWith(metric.field!, m.id));
const targetLabel = calculateLabel(targetMetric!, metrics, fields);
const targetLabel = calculateLabel(targetMetric!, metrics, fields, isThrowErrorOnFieldNotFound);

// For percentiles we need to parse the field id to extract the percentile
// the user configured in the percentile aggregation and specified in the
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/vis_type_timeseries/common/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ export enum TOOLTIP_MODES {
SHOW_ALL = 'show_all',
SHOW_FOCUSED = 'show_focused',
}

export enum DATA_FORMATTERS {
BYTES = 'bytes',
CUSTOM = 'custom',
DEFAULT = 'default',
DURATION = 'duration',
NUMBER = 'number',
PERCENT = 'percent',
}
1 change: 1 addition & 0 deletions src/plugins/vis_type_timeseries/common/types/vis_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface PanelSeries {
export interface PanelData {
id: string;
label: string;
labelFormatted?: string;
data: PanelDataArray[];
seriesId: string;
splitByLabel: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,39 @@
* Side Public License, v 1.
*/

import React, { HTMLAttributes } from 'react';
import React, { useMemo, useEffect, HTMLAttributes } from 'react';
// @ts-ignore
import { aggToComponent } from '../lib/agg_to_component';
// @ts-ignore
import { isMetricEnabled } from '../../lib/check_ui_restrictions';
// @ts-expect-error not typed yet
import { seriesChangeHandler } from '../lib/series_change_handler';
import { checkIfNumericMetric } from '../lib/check_if_numeric_metric';
import { getFormatterType } from '../lib/get_formatter_type';
import { UnsupportedAgg } from './unsupported_agg';
import { TemporaryUnsupportedAgg } from './temporary_unsupported_agg';
import { DATA_FORMATTERS } from '../../../../common/enums';
import type { Metric, Panel, Series, SanitizedFieldType } from '../../../../common/types';
import { DragHandleProps } from '../../../types';
import { TimeseriesUIRestrictions } from '../../../../common/ui_restrictions';
import type { DragHandleProps } from '../../../types';
import type { TimeseriesUIRestrictions } from '../../../../common/ui_restrictions';

interface AggProps extends HTMLAttributes<HTMLElement> {
disableDelete: boolean;
fields: Record<string, SanitizedFieldType[]>;
name: string;
model: Metric;
panel: Panel;
series: Series;
siblings: Metric[];
uiRestrictions: TimeseriesUIRestrictions;
dragHandleProps: DragHandleProps;
onChange: (part: Partial<Series>) => void;
onAdd: () => void;
onChange: () => void;
onDelete: () => void;
}

export function Agg(props: AggProps) {
const { model, uiRestrictions } = props;
const { model, uiRestrictions, series, name, onChange, fields, siblings } = props;

let Component = aggToComponent[model.type];

Expand All @@ -50,6 +56,34 @@ export function Agg(props: AggProps) {
const indexPattern = props.series.override_index_pattern
? props.series.series_index_pattern
: props.panel.index_pattern;
const isKibanaIndexPattern = props.panel.use_kibana_indexes || indexPattern === '';

const onAggChange = useMemo(
() => seriesChangeHandler({ name, model: series, onChange }, siblings),
[name, onChange, siblings, series]
);

useEffect(() => {
// formatter is based on the last agg, i.e. active or resulting one as pipeline
if (siblings[siblings.length - 1]?.id === model.id) {
const formatterType = getFormatterType(series.formatter);
const isNumericMetric = checkIfNumericMetric(model, fields, indexPattern);
const isNumberFormatter = ![DATA_FORMATTERS.DEFAULT, DATA_FORMATTERS.CUSTOM].includes(
formatterType
);

if (isNumberFormatter && !isNumericMetric) {
onChange({ formatter: DATA_FORMATTERS.DEFAULT });
}
// in case of string index pattern mode, change default formatter depending on metric type
// "number" formatter for numeric metric and "" as custom formatter for any other type
if (formatterType === DATA_FORMATTERS.DEFAULT && !isKibanaIndexPattern) {
onChange({
formatter: isNumericMetric ? DATA_FORMATTERS.NUMBER : '',
});
}
}
}, [indexPattern, model, onChange, fields, series.formatter, isKibanaIndexPattern, siblings]);

return (
<div className={props.className} style={style}>
Expand All @@ -58,7 +92,7 @@ export function Agg(props: AggProps) {
disableDelete={props.disableDelete}
model={props.model}
onAdd={props.onAdd}
onChange={props.onChange}
onChange={onAggChange}
onDelete={props.onDelete}
panel={props.panel}
series={props.series}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { EuiDraggable, EuiDroppable } from '@elastic/eui';

import { Agg } from './agg';
// @ts-ignore
import { seriesChangeHandler } from '../lib/series_change_handler';
import { handleAdd, handleDelete } from '../lib/collection_actions';
import { newMetricAggFn } from '../lib/new_metric_agg_fn';
import type { Panel, Series, SanitizedFieldType } from '../../../../common/types';
Expand All @@ -26,16 +25,14 @@ export interface AggsProps {
model: Series;
fields: Record<string, SanitizedFieldType[]>;
uiRestrictions: TimeseriesUIRestrictions;
onChange(): void;
onChange(part: Partial<Series>): void;
}

export class Aggs extends PureComponent<AggsProps> {
render() {
const { panel, model, fields, uiRestrictions } = this.props;
const { panel, model, fields, name, uiRestrictions, onChange } = this.props;
const list = model.metrics;

const onChange = seriesChangeHandler(this.props, list);

return (
<EuiDroppable droppableId={`${DROPPABLE_ID}:${model.id}`} type="MICRO" spacing="s">
{list.map((row, idx) => (
Expand All @@ -51,6 +48,7 @@ export class Aggs extends PureComponent<AggsProps> {
key={row.id}
disableDelete={list.length < 2}
fields={fields}
name={name}
model={row}
onAdd={() => handleAdd(this.props, newMetricAggFn)}
onChange={onChange}
Expand Down
Loading