Skip to content

Commit

Permalink
[TSVB] Fix percentiles band mode (elastic#60741)
Browse files Browse the repository at this point in the history
* Fix percentiles band mode

* Add support of bar chart, fix tests

* Use accessor formatters

* Fix tests
  • Loading branch information
sulemanof committed Mar 23, 2020
1 parent 27f022e commit b12eb8e
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class PercentilesUi extends Component {
<EuiFlexItem style={optionsStyle} grow={false}>
<EuiFieldNumber
id={htmlId('fillTo')}
min={0}
max={100}
step={1}
onChange={this.handleTextChange(model, 'percentile')}
value={Number(model.percentile)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const GRID_LINE_CONFIG = {
export const X_ACCESSOR_INDEX = 0;
export const STACK_ACCESSORS = [0];
export const Y_ACCESSOR_INDEXES = [1];
export const Y0_ACCESSOR_INDEXES = [2];

export const STACKED_OPTIONS = {
NONE: 'none',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React from 'react';
import { ScaleType, AreaSeries } from '@elastic/charts';
import { getAreaStyles } from '../utils/series_styles';
import { ChartsEntities } from '../model/charts';
import { X_ACCESSOR_INDEX, Y_ACCESSOR_INDEXES } from '../../../constants';
import { X_ACCESSOR_INDEX, Y_ACCESSOR_INDEXES, Y0_ACCESSOR_INDEXES } from '../../../constants';

export function AreaSeriesDecorator({
seriesId,
Expand All @@ -40,6 +40,8 @@ export function AreaSeriesDecorator({
enableHistogramMode,
useDefaultGroupDomain,
sortIndex,
y1AccessorFormat,
y0AccessorFormat,
}) {
const id = seriesId;
const groupId = seriesGroupId;
Expand All @@ -54,6 +56,9 @@ export function AreaSeriesDecorator({
hideInLegend,
xAccessor: X_ACCESSOR_INDEX,
yAccessors: Y_ACCESSOR_INDEXES,
y0Accessors: lines.mode === 'band' ? Y0_ACCESSOR_INDEXES : undefined,
y1AccessorFormat,
y0AccessorFormat,
stackAccessors,
stackAsPercentage,
xScaleType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React from 'react';
import { ScaleType, BarSeries } from '@elastic/charts';
import { getBarStyles } from '../utils/series_styles';
import { ChartsEntities } from '../model/charts';
import { X_ACCESSOR_INDEX, Y_ACCESSOR_INDEXES } from '../../../constants';
import { X_ACCESSOR_INDEX, Y_ACCESSOR_INDEXES, Y0_ACCESSOR_INDEXES } from '../../../constants';

export function BarSeriesDecorator({
seriesId,
Expand All @@ -39,6 +39,8 @@ export function BarSeriesDecorator({
enableHistogramMode,
useDefaultGroupDomain,
sortIndex,
y1AccessorFormat,
y0AccessorFormat,
}) {
const id = seriesId;
const groupId = seriesGroupId;
Expand All @@ -53,6 +55,9 @@ export function BarSeriesDecorator({
hideInLegend,
xAccessor: X_ACCESSOR_INDEX,
yAccessors: Y_ACCESSOR_INDEXES,
y0Accessors: bars.mode === 'band' ? Y0_ACCESSOR_INDEXES : undefined,
y1AccessorFormat,
y0AccessorFormat,
stackAccessors,
stackAsPercentage,
xScaleType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ export const TimeSeries = ({
stack,
points,
useDefaultGroupDomain,
y1AccessorFormat,
y0AccessorFormat,
},
sortIndex
) => {
Expand All @@ -182,6 +184,8 @@ export const TimeSeries = ({
enableHistogramMode={enableHistogramMode}
useDefaultGroupDomain={useDefaultGroupDomain}
sortIndex={sortIndex}
y1AccessorFormat={y1AccessorFormat}
y0AccessorFormat={y0AccessorFormat}
/>
);
}
Expand All @@ -206,6 +210,8 @@ export const TimeSeries = ({
enableHistogramMode={enableHistogramMode}
useDefaultGroupDomain={useDefaultGroupDomain}
sortIndex={sortIndex}
y1AccessorFormat={y1AccessorFormat}
y0AccessorFormat={y0AccessorFormat}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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],
]);
Expand Down

0 comments on commit b12eb8e

Please sign in to comment.