From 4f182360e35e871118773b230b9596b3c07efc9c Mon Sep 17 00:00:00 2001 From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com> Date: Tue, 24 Mar 2020 09:03:55 +0300 Subject: [PATCH] [TSVB] Fix percentiles band mode (#60741) (#60924) * Fix percentiles band mode * Add support of bar chart, fix tests * Use accessor formatters * Fix tests --- .../public/components/aggs/percentile_ui.js | 2 + .../public/visualizations/constants/chart.js | 1 + .../timeseries/decorators/area_decorator.js | 7 ++- .../timeseries/decorators/bar_decorator.js | 7 ++- .../visualizations/views/timeseries/index.js | 6 +++ .../response_processors/series/percentile.js | 51 ++++++++++--------- .../series/percentile.test.js | 44 +++++----------- 7 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js index b931c8084a61e..f94c2f609da8f 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js @@ -135,6 +135,8 @@ class PercentilesUi extends Component { { @@ -181,6 +183,8 @@ export const TimeSeries = ({ enableHistogramMode={enableHistogramMode} useDefaultGroupDomain={useDefaultGroupDomain} sortIndex={sortIndex} + y1AccessorFormat={y1AccessorFormat} + y0AccessorFormat={y0AccessorFormat} /> ); } @@ -205,6 +209,8 @@ export const TimeSeries = ({ enableHistogramMode={enableHistogramMode} useDefaultGroupDomain={useDefaultGroupDomain} sortIndex={sortIndex} + y1AccessorFormat={y1AccessorFormat} + y0AccessorFormat={y0AccessorFormat} /> ); } 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 669a96a43ff8d..00fb48c88ec3f 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 @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import { getAggValue } from '../../helpers/get_agg_value'; import { getDefaultDecoration } from '../../helpers/get_default_decoration'; import { getSplits } from '../../helpers/get_splits'; @@ -35,41 +34,45 @@ export function percentile(resp, panel, series, meta) { getSplits(resp, panel, series, meta).forEach(split => { metric.percentiles.forEach(percentile => { const percentileValue = percentile.value ? percentile.value : 0; - const label = `${split.label} (${percentileValue})`; + const id = `${split.id}:${percentile.id}`; const data = split.timeseries.buckets.map(bucket => { - const m = _.assign({}, metric, { percent: percentileValue }); - return [bucket.key, getAggValue(bucket, m)]; + const higherMetric = { ...metric, percent: percentileValue }; + const serieData = [bucket.key, getAggValue(bucket, higherMetric)]; + + if (percentile.mode === 'band') { + const lowerMetric = { ...metric, percent: percentile.percentile }; + serieData.push(getAggValue(bucket, lowerMetric)); + } + + return serieData; }); if (percentile.mode === 'band') { - const fillData = split.timeseries.buckets.map(bucket => { - const m = _.assign({}, metric, { percent: percentile.percentile }); - return [bucket.key, getAggValue(bucket, m)]; - }); results.push({ - id: `${split.id}:${percentile.id}`, + id, color: split.color, - label, + label: split.label, data, - lines: { show: true, fill: percentile.shade, lineWidth: 0 }, - points: { show: false }, - legend: false, - fillBetween: `${split.id}:${percentile.id}:${percentile.percentile}`, - }); - results.push({ - id: `${split.id}:${percentile.id}:${percentile.percentile}`, - color: split.color, - label, - data: fillData, - lines: { show: true, fill: false, lineWidth: 0 }, - legend: false, + lines: { + show: series.chart_type === 'line', + fill: Number(percentile.shade), + lineWidth: 0, + mode: 'band', + }, + bars: { + show: series.chart_type === 'bar', + fill: Number(percentile.shade), + mode: 'band', + }, points: { show: false }, + y1AccessorFormat: ` (${percentileValue})`, + y0AccessorFormat: ` (${percentile.percentile})`, }); } else { const decoration = getDefaultDecoration(series); results.push({ - id: `${split.id}:${percentile.id}`, + id, color: split.color, - label, + label: `${split.label} (${percentileValue})`, 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 9cb08de8dad23..aec1c45cf97e1 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 @@ -89,63 +89,45 @@ describe('percentile(resp, panel, series)', () => { test('creates a series', () => { const next = results => results; const results = percentile(resp, panel, series)(next)([]); - expect(results).toHaveLength(3); + 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('fillBetween', 'test:10-90:90'); - expect(results[0]).toHaveProperty('label', 'Percentile of cpu (10)'); - expect(results[0]).toHaveProperty('legend', false); + expect(results[0]).toHaveProperty('label', 'Percentile of cpu'); expect(results[0]).toHaveProperty('lines'); expect(results[0].lines).toEqual({ fill: 0.2, lineWidth: 0, show: true, + mode: 'band', }); expect(results[0]).toHaveProperty('points'); expect(results[0].points).toEqual({ show: false }); expect(results[0].data).toEqual([ - [1, 1], - [2, 1.2], + [1, 1, 5], + [2, 1.2, 5.3], ]); - expect(results[1]).toHaveProperty('id', 'test:10-90:90'); + expect(results[1]).toHaveProperty('id', 'test:50'); expect(results[1]).toHaveProperty('color', 'rgb(255, 0, 0)'); - expect(results[1]).toHaveProperty('label', 'Percentile of cpu (10)'); - expect(results[1]).toHaveProperty('legend', false); + expect(results[1]).toHaveProperty('label', 'Percentile of cpu (50)'); + expect(results[1]).toHaveProperty('stack', false); expect(results[1]).toHaveProperty('lines'); expect(results[1].lines).toEqual({ - fill: false, - lineWidth: 0, - show: true, - }); - expect(results[1]).toHaveProperty('points'); - expect(results[1].points).toEqual({ show: false }); - expect(results[1].data).toEqual([ - [1, 5], - [2, 5.3], - ]); - - expect(results[2]).toHaveProperty('id', 'test:50'); - expect(results[2]).toHaveProperty('color', 'rgb(255, 0, 0)'); - expect(results[2]).toHaveProperty('label', 'Percentile of cpu (50)'); - expect(results[2]).toHaveProperty('stack', false); - expect(results[2]).toHaveProperty('lines'); - expect(results[2].lines).toEqual({ fill: 0, lineWidth: 1, show: true, steps: false, }); - expect(results[2]).toHaveProperty('bars'); - expect(results[2].bars).toEqual({ + expect(results[1]).toHaveProperty('bars'); + expect(results[1].bars).toEqual({ fill: 0, lineWidth: 1, show: false, }); - expect(results[2]).toHaveProperty('points'); - expect(results[2].points).toEqual({ show: true, lineWidth: 1, radius: 1 }); - expect(results[2].data).toEqual([ + expect(results[1]).toHaveProperty('points'); + expect(results[1].points).toEqual({ show: true, lineWidth: 1, radius: 1 }); + expect(results[1].data).toEqual([ [1, 2.5], [2, 2.7], ]);