diff --git a/src/plugins/vis_type_timeseries/common/constants.ts b/src/plugins/vis_type_timeseries/common/constants.ts
index 1debfaf951e999..bddbf095e895eb 100644
--- a/src/plugins/vis_type_timeseries/common/constants.ts
+++ b/src/plugins/vis_type_timeseries/common/constants.ts
@@ -14,3 +14,4 @@ export const ROUTES = {
FIELDS: '/api/metrics/fields',
};
export const USE_KIBANA_INDEXES_KEY = 'use_kibana_indexes';
+export const TSVB_DEFAULT_COLOR = '#68BC00';
diff --git a/src/plugins/vis_type_timeseries/common/types/panel_model.ts b/src/plugins/vis_type_timeseries/common/types/panel_model.ts
index 7eea4e64e7c6f7..2ac9125534ac79 100644
--- a/src/plugins/vis_type_timeseries/common/types/panel_model.ts
+++ b/src/plugins/vis_type_timeseries/common/types/panel_model.ts
@@ -24,6 +24,7 @@ interface Percentile {
shade?: number | string;
value?: number | string;
percentile?: string;
+ color?: string;
}
export interface Metric {
@@ -52,6 +53,7 @@ export interface Metric {
type: string;
value?: string;
values?: string[];
+ colors?: string[];
size?: string | number;
agg_with?: string;
order?: string;
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/histogram_support.test.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/histogram_support.test.js
index c536856327f283..c4a49a393acd68 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/histogram_support.test.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/histogram_support.test.js
@@ -27,7 +27,7 @@ const runTest = (aggType, name, test, additionalProps = {}) => {
...additionalProps,
};
const series = { ...SERIES, metrics: [metric] };
- const panel = { ...PANEL, series };
+ const panel = PANEL;
it(name, () => {
const wrapper = mountWithIntl(
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js
index 45bb5387c5cd3d..94adb37de156b2 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js
@@ -102,7 +102,13 @@ export function PercentileAgg(props) {
/>
}
>
-
+
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.test.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.test.tsx
new file mode 100644
index 00000000000000..7b08715ba1a934
--- /dev/null
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.test.tsx
@@ -0,0 +1,49 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React from 'react';
+import { shallowWithIntl } from '@kbn/test/jest';
+import { MultiValueRow } from './multi_value_row';
+import { ColorPicker } from '../../color_picker';
+
+describe('MultiValueRow', () => {
+ const model = {
+ id: 95,
+ value: '95',
+ color: '#00028',
+ };
+ const props = {
+ model,
+ enableColorPicker: true,
+ onChange: jest.fn(),
+ onDelete: jest.fn(),
+ onAdd: jest.fn(),
+ disableAdd: false,
+ disableDelete: false,
+ };
+
+ const wrapper = shallowWithIntl();
+
+ it('displays a color picker if the enableColorPicker prop is true', () => {
+ expect(wrapper.find(ColorPicker).length).toEqual(1);
+ });
+
+ it('not displays a color picker if the enableColorPicker prop is false', () => {
+ const newWrapper = shallowWithIntl();
+ expect(newWrapper.find(ColorPicker).length).toEqual(0);
+ });
+
+ it('sets the picker color to the model color', () => {
+ expect(wrapper.find(ColorPicker).prop('value')).toEqual('#00028');
+ });
+
+ it('should have called the onChange function on color change', () => {
+ wrapper.find(ColorPicker).simulate('change');
+ expect(props.onChange).toHaveBeenCalled();
+ });
+});
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.tsx
index 8fa65e6ce40db5..d1174ce95367c3 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.tsx
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.tsx
@@ -10,17 +10,21 @@ import React, { ChangeEvent } from 'react';
import { get } from 'lodash';
import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
+import { TSVB_DEFAULT_COLOR } from '../../../../../common/constants';
import { AddDeleteButtons } from '../../add_delete_buttons';
+import { ColorPicker, ColorProps } from '../../color_picker';
interface MultiValueRowProps {
model: {
id: number;
value: string;
+ color: string;
};
disableAdd: boolean;
disableDelete: boolean;
- onChange: ({ value, id }: { id: number; value: string }) => void;
+ enableColorPicker: boolean;
+ onChange: ({ value, id, color }: { id: number; value: string; color: string }) => void;
onDelete: (model: { id: number; value: string }) => void;
onAdd: () => void;
}
@@ -32,6 +36,7 @@ export const MultiValueRow = ({
onAdd,
disableAdd,
disableDelete,
+ enableColorPicker,
}: MultiValueRowProps) => {
const onFieldNumberChange = (event: ChangeEvent) =>
onChange({
@@ -39,9 +44,25 @@ export const MultiValueRow = ({
value: get(event, 'target.value'),
});
+ const onColorPickerChange = (props: ColorProps) =>
+ onChange({
+ ...model,
+ color: props?.color || TSVB_DEFAULT_COLOR,
+ });
+
return (
+ {enableColorPicker && (
+
+
+
+ )}
{
const { panel, fields, indexPattern } = props;
- const defaults = { values: [''] };
+ const defaults = { values: [''], colors: [TSVB_DEFAULT_COLOR] };
const model = { ...defaults, ...props.model };
const htmlId = htmlIdGenerator();
@@ -56,11 +59,17 @@ export const PercentileRankAgg = (props: PercentileRankAggProps) => {
const handleChange = createChangeHandler(props.onChange, model);
const handleSelectChange = createSelectHandler(handleChange);
const handleNumberChange = createNumberHandler(handleChange);
+ const percentileRankSeries =
+ panel.series.find((s) => s.id === props.series.id) || panel.series[0];
+ // If the series is grouped by, then these colors are not respected, no need to display the color picker */
+ const isGroupedBy = panel.series.length > 0 && percentileRankSeries.split_mode !== 'everything';
+ const enableColorPicker = !isGroupedBy && !['table', 'metric', 'markdown'].includes(panel.type);
- const handlePercentileRankValuesChange = (values: Metric['values']) => {
+ const handlePercentileRankValuesChange = (values: Metric['values'], colors: Metric['colors']) => {
handleChange({
...model,
values,
+ colors,
});
};
return (
@@ -119,8 +128,10 @@ export const PercentileRankAgg = (props: PercentileRankAggProps) => {
disableAdd={isTablePanel}
disableDelete={isTablePanel}
showOnlyLastRow={isTablePanel}
- model={model.values!}
+ values={model.values!}
+ colors={model.colors!}
onChange={handlePercentileRankValuesChange}
+ enableColorPicker={enableColorPicker}
/>
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.tsx
index 2441611b87d316..f3eb290f77a08c 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.tsx
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.tsx
@@ -10,35 +10,43 @@ import React from 'react';
import { last } from 'lodash';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { TSVB_DEFAULT_COLOR } from '../../../../../common/constants';
import { MultiValueRow } from './multi_value_row';
interface PercentileRankValuesProps {
- model: Array;
+ values: string[];
+ colors: string[];
disableDelete: boolean;
disableAdd: boolean;
showOnlyLastRow: boolean;
- onChange: (values: any[]) => void;
+ enableColorPicker: boolean;
+ onChange: (values: string[], colors: string[]) => void;
}
export const PercentileRankValues = (props: PercentileRankValuesProps) => {
- const model = props.model || [];
- const { onChange, disableAdd, disableDelete, showOnlyLastRow } = props;
+ const values = props.values || [];
+ const colors = props.colors || [];
+ const { onChange, disableAdd, disableDelete, showOnlyLastRow, enableColorPicker } = props;
- const onChangeValue = ({ value, id }: { value: string; id: number }) => {
- model[id] = value;
+ const onChangeValue = ({ value, id, color }: { value: string; id: number; color: string }) => {
+ values[id] = value;
+ colors[id] = color;
- onChange(model);
+ onChange(values, colors);
};
const onDeleteValue = ({ id }: { id: number }) =>
- onChange(model.filter((item, currentIndex) => id !== currentIndex));
- const onAddValue = () => onChange([...model, '']);
+ onChange(
+ values.filter((item, currentIndex) => id !== currentIndex),
+ colors.filter((item, currentIndex) => id !== currentIndex)
+ );
+ const onAddValue = () => onChange([...values, ''], [...colors, TSVB_DEFAULT_COLOR]);
const renderRow = ({
rowModel,
disableDeleteRow,
disableAddRow,
}: {
- rowModel: { id: number; value: string };
+ rowModel: { id: number; value: string; color: string };
disableDeleteRow: boolean;
disableAddRow: boolean;
}) => (
@@ -50,6 +58,7 @@ export const PercentileRankValues = (props: PercentileRankValuesProps) => {
disableDelete={disableDeleteRow}
disableAdd={disableAddRow}
model={rowModel}
+ enableColorPicker={enableColorPicker}
/>
);
@@ -59,19 +68,21 @@ export const PercentileRankValues = (props: PercentileRankValuesProps) => {
{showOnlyLastRow &&
renderRow({
rowModel: {
- id: model.length - 1,
- value: last(model) || '',
+ id: values.length - 1,
+ value: last(values) || '',
+ color: last(colors) || TSVB_DEFAULT_COLOR,
},
disableAddRow: true,
disableDeleteRow: true,
})}
{!showOnlyLastRow &&
- model.map((value, id, array) =>
+ values.map((value, id, array) =>
renderRow({
rowModel: {
id,
value: value || '',
+ color: colors[id] || TSVB_DEFAULT_COLOR,
},
disableAddRow: disableAdd,
disableDeleteRow: disableDelete || array.length < 2,
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js
index 5b8b56849fcdad..bfd41b9cdfafca 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js
@@ -10,6 +10,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { i18n } from '@kbn/i18n';
import _ from 'lodash';
+import { TSVB_DEFAULT_COLOR } from '../../../../common/constants';
import { collectionActions } from '../lib/collection_actions';
import { AddDeleteButtons } from '../add_delete_buttons';
import uuid from 'uuid';
@@ -23,10 +24,11 @@ import {
EuiFlexGrid,
EuiPanel,
} from '@elastic/eui';
+import { ColorPicker } from '../color_picker';
import { FormattedMessage } from '@kbn/i18n/react';
export const newPercentile = (opts) => {
- return _.assign({ id: uuid.v1(), mode: 'line', shade: 0.2 }, opts);
+ return _.assign({ id: uuid.v1(), mode: 'line', shade: 0.2, color: TSVB_DEFAULT_COLOR }, opts);
};
export class Percentiles extends Component {
@@ -39,11 +41,20 @@ export class Percentiles extends Component {
};
}
+ handleColorChange(item) {
+ return (val) => {
+ const handleChange = collectionActions.handleChange.bind(null, this.props);
+ handleChange(_.assign({}, item, val));
+ };
+ }
+
renderRow = (row, i, items) => {
- const defaults = { value: '', percentile: '', shade: '' };
+ const defaults = { value: '', percentile: '', shade: '', color: TSVB_DEFAULT_COLOR };
const model = { ...defaults, ...row };
- const { panel } = this.props;
+ const { panel, seriesId } = this.props;
const flexItemStyle = { minWidth: 100 };
+ const percentileSeries = panel.series.find((s) => s.id === seriesId) || panel.series[0];
+ const isGroupedBy = panel.series.length > 0 && percentileSeries.split_mode !== 'everything';
const percentileFieldNumber = (
@@ -106,7 +117,19 @@ export class Percentiles extends Component {
-
+
+ {/* If the series is grouped by, then these colors are not respected,
+ no need to display the color picker */}
+ {!isGroupedBy && !['table', 'metric', 'markdown'].includes(panel.type) && (
+
+
+
+ )}
{percentileFieldNumber}
{
+ const props = {
+ name: 'percentiles',
+ model: {
+ values: ['100', '200'],
+ colors: ['#00028', 'rgba(96,146,192,1)'],
+ percentiles: [
+ {
+ id: 'ece1c4b0-fb4b-11eb-a845-3de627f78e15',
+ mode: 'line',
+ shade: 0.2,
+ color: '#00028',
+ value: 50,
+ },
+ ],
+ },
+ panel: {
+ time_range_mode: 'entire_time_range',
+ series: [
+ {
+ axis_position: 'right',
+ chart_type: 'line',
+ color: '#68BC00',
+ fill: 0.5,
+ formatter: 'number',
+ id: '64e4b07a-206e-4a0d-87e1-d6f5864f4acb',
+ label: '',
+ line_width: 1,
+ metrics: [
+ {
+ values: ['100', '200'],
+ colors: ['#68BC00', 'rgba(96,146,192,1)'],
+ field: 'AvgTicketPrice',
+ id: 'a64ed16c-c642-4705-8045-350206595530',
+ type: 'percentile',
+ percentiles: [
+ {
+ id: 'ece1c4b0-fb4b-11eb-a845-3de627f78e15',
+ mode: 'line',
+ shade: 0.2,
+ color: '#68BC00',
+ value: 50,
+ },
+ ],
+ },
+ ],
+ palette: {
+ name: 'default',
+ type: 'palette',
+ },
+ point_size: 1,
+ separate_axis: 0,
+ split_mode: 'everything',
+ stacked: 'none',
+ type: 'timeseries',
+ },
+ ],
+ show_grid: 1,
+ show_legend: 1,
+ time_field: '',
+ tooltip_mode: 'show_all',
+ type: 'timeseries',
+ use_kibana_indexes: true,
+ },
+ seriesId: '64e4b07a-206e-4a0d-87e1-d6f5864f4acb',
+ id: 'iecdd7ef1-fb4b-11eb-8db9-69be3a5b3be0',
+ onBlur: jest.fn(),
+ onChange: jest.fn(),
+ onFocus: jest.fn(),
+ };
+
+ const wrapper = shallowWithIntl();
+
+ it('displays a color picker if is not grouped by', () => {
+ expect(wrapper.find(ColorPicker).length).toEqual(1);
+ });
+
+ it('sets the picker color to the model color', () => {
+ expect(wrapper.find(ColorPicker).prop('value')).toEqual('#00028');
+ });
+
+ it('should have called the onChange function on color change', () => {
+ wrapper.find(ColorPicker).simulate('change');
+ expect(props.onChange).toHaveBeenCalled();
+ });
+});
diff --git a/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx b/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx
index 280e4eda338998..fbfec011210365 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx
+++ b/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx
@@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n';
const COMMAS_NUMS_ONLY_RE = /[^0-9,]/g;
-interface ColorProps {
+export interface ColorProps {
[key: string]: string | null;
}
diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts
index a2efe39b2c7f0e..364de9c6b42458 100644
--- a/src/plugins/vis_type_timeseries/public/metrics_type.ts
+++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts
@@ -11,6 +11,7 @@ import uuid from 'uuid/v4';
import { TSVB_EDITOR_NAME } from './application/editor_controller';
import { PANEL_TYPES, TOOLTIP_MODES } from '../common/enums';
import { isStringTypeIndexPattern } from '../common/index_patterns_utils';
+import { TSVB_DEFAULT_COLOR } from '../common/constants';
import { toExpressionAst } from './to_ast';
import { VIS_EVENT_TO_TRIGGER, VisGroups, VisParams } from '../../visualizations/public';
import { getDataStart } from './services';
@@ -30,7 +31,7 @@ export const metricsVisDefinition = {
series: [
{
id: uuid(),
- color: '#68BC00',
+ color: TSVB_DEFAULT_COLOR,
split_mode: 'everything',
palette: {
type: 'palette',
diff --git a/src/plugins/vis_type_timeseries/public/test_utils/index.ts b/src/plugins/vis_type_timeseries/public/test_utils/index.ts
index d5121237cd2a76..b88c765baf3a35 100644
--- a/src/plugins/vis_type_timeseries/public/test_utils/index.ts
+++ b/src/plugins/vis_type_timeseries/public/test_utils/index.ts
@@ -35,5 +35,5 @@ export const SERIES = {
export const PANEL = {
type: 'timeseries',
index_pattern: INDEX_PATTERN,
- series: SERIES,
+ series: [SERIES],
};
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js
index 5eec0f8f2c6f6b..b7e0026132af3b 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js
@@ -38,7 +38,10 @@ export function percentile(resp, panel, series, meta, extractFields) {
if (percentile.mode === 'band') {
results.push({
id,
- color: split.color,
+ color:
+ series.split_mode === 'everything' && percentile.color
+ ? percentile.color
+ : split.color,
label: split.label,
data,
lines: {
@@ -60,8 +63,11 @@ export function percentile(resp, panel, series, meta, extractFields) {
const decoration = getDefaultDecoration(series);
results.push({
id,
- color: split.color,
- label: `${split.label} (${percentileValue})`,
+ color:
+ series.split_mode === 'everything' && percentile.color
+ ? percentile.color
+ : split.color,
+ label: `(${percentileValue}) ${split.label}`,
data,
...decoration,
});
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js
index 9174876c768c51..de304913d6c694 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js
@@ -31,7 +31,7 @@ describe('percentile(resp, panel, series)', () => {
type: 'percentile',
field: 'cpu',
percentiles: [
- { id: '10-90', mode: 'band', value: 10, percentile: 90, shade: 0.2 },
+ { id: '10-90', mode: 'band', value: 10, percentile: 90, shade: 0.2, color: '#000028' },
{ id: '50', mode: 'line', value: 50 },
],
},
@@ -84,7 +84,7 @@ describe('percentile(resp, panel, series)', () => {
expect(results).toHaveLength(2);
expect(results[0]).toHaveProperty('id', 'test:10-90');
- expect(results[0]).toHaveProperty('color', 'rgb(255, 0, 0)');
+ expect(results[0]).toHaveProperty('color', '#000028');
expect(results[0]).toHaveProperty('label', 'Percentile of cpu');
expect(results[0]).toHaveProperty('lines');
expect(results[0].lines).toEqual({
@@ -102,7 +102,7 @@ describe('percentile(resp, panel, series)', () => {
expect(results[1]).toHaveProperty('id', 'test:50');
expect(results[1]).toHaveProperty('color', 'rgb(255, 0, 0)');
- expect(results[1]).toHaveProperty('label', 'Percentile of cpu (50)');
+ expect(results[1]).toHaveProperty('label', '(50) Percentile of cpu');
expect(results[1]).toHaveProperty('stack', false);
expect(results[1]).toHaveProperty('lines');
expect(results[1].lines).toEqual({
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js
index 96b004d4b539e2..7203be4d2feb6e 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js
@@ -34,8 +34,11 @@ export function percentileRank(resp, panel, series, meta, extractFields) {
results.push({
data,
id: `${split.id}:${percentileRank}:${index}`,
- label: `${split.label} (${percentileRank || 0})`,
- color: split.color,
+ label: `(${percentileRank || 0}) ${split.label}`,
+ color:
+ series.split_mode === 'everything' && metric.colors
+ ? metric.colors[index]
+ : split.color,
...getDefaultDecoration(series),
});
});
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.test.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.test.ts
new file mode 100644
index 00000000000000..c1e5bd006ef688
--- /dev/null
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.test.ts
@@ -0,0 +1,94 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+// @ts-expect-error no typed yet
+import { percentileRank } from './percentile_rank';
+import type { Panel, Series } from '../../../../../common/types';
+
+describe('percentile_rank(resp, panel, series, meta, extractFields)', () => {
+ let panel: Panel;
+ let series: Series;
+ let resp: unknown;
+ beforeEach(() => {
+ panel = {
+ time_field: 'timestamp',
+ } as Panel;
+ series = ({
+ chart_type: 'line',
+ stacked: 'stacked',
+ line_width: 1,
+ point_size: 1,
+ fill: 0,
+ color: 'rgb(255, 0, 0)',
+ id: 'test',
+ split_mode: 'everything',
+ metrics: [
+ {
+ id: 'pct_rank',
+ type: 'percentile_rank',
+ field: 'cpu',
+ values: ['1000', '500'],
+ colors: ['#000028', '#0000FF'],
+ },
+ ],
+ } as unknown) as Series;
+ resp = {
+ aggregations: {
+ test: {
+ timeseries: {
+ buckets: [
+ {
+ key: 1,
+ pct_rank: {
+ values: { '500.0': 1, '1000.0': 2 },
+ },
+ },
+ {
+ key: 2,
+ pct_rank: {
+ values: { '500.0': 3, '1000.0': 1 },
+ },
+ },
+ ],
+ },
+ },
+ },
+ };
+ });
+
+ test('calls next when finished', async () => {
+ const next = jest.fn();
+
+ await percentileRank(resp, panel, series, {})(next)([]);
+
+ expect(next.mock.calls.length).toEqual(1);
+ });
+
+ test('creates a series', async () => {
+ const next = (results: unknown) => results;
+ const results = await percentileRank(resp, panel, series, {})(next)([]);
+
+ expect(results).toHaveLength(2);
+
+ expect(results[0]).toHaveProperty('id', 'test:1000:0');
+ expect(results[0]).toHaveProperty('color', '#000028');
+ expect(results[0]).toHaveProperty('label', '(1000) Percentile Rank of cpu');
+ expect(results[0].data).toEqual([
+ [1, 2],
+ [2, 1],
+ ]);
+
+ expect(results[1]).toHaveProperty('id', 'test:500:1');
+ expect(results[1]).toHaveProperty('color', '#0000FF');
+ expect(results[1]).toHaveProperty('label', '(500) Percentile Rank of cpu');
+ expect(results[1].data).toEqual([
+ [1, 1],
+ [2, 3],
+ ]);
+ });
+});