Skip to content

Commit

Permalink
[TSVB][Top N aggregation] Unable to deal with negative values (#43581)
Browse files Browse the repository at this point in the history
* [TSVB][Top N aggregation] Unable to deal with negative values

* change logic only for negative values

* fix PR comments

* fix scss styles

* fix calculating interval length

* Fix PR comments
  • Loading branch information
alexwizp authored Sep 6, 2019
1 parent 0d1f3cf commit bf9c86f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
}

.tvbVisTopN__innerBar {
min-height: $euiSize;
position: relative;

> div {
width: 100%;
min-height: $euiSize;
}
}

.tvbVisTopN--reversed {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ import React, { Component } from 'react';
import { getLastValue } from '../../../common/get_last_value';
import reactcss from 'reactcss';

const RENDER_MODES = {
POSITIVE: 'positive',
NEGATIVE: 'negative',
MIXED: 'mixed',
};

export class TopN extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -59,20 +65,61 @@ export class TopN extends Component {
};
}

renderRow(maxValue) {
static getRenderMode = (min, max) => {
if (min >= 0) {
return RENDER_MODES.POSITIVE;
} else if (max < 0) {
return RENDER_MODES.NEGATIVE;
}
return RENDER_MODES.MIXED;
};

static calcInnerBarStyles = (renderMode, isPositive) => {
if (renderMode === RENDER_MODES.MIXED) {
return {
[isPositive ? 'marginLeft' : 'marginRight']: '50%',
};
}
return {};
};

static calcInnerBarDivStyles = (item, width, isPositive) => {
return {
backgroundColor: item.color,
width: width + '%',
float: isPositive ? 'left' : 'right',
};
};

static calcDomain = (renderMode, min, max) => {
if (renderMode === RENDER_MODES.MIXED) {
return Math.max(max, Math.abs(min));
} else if (renderMode === RENDER_MODES.NEGATIVE) {
return Math.abs(min);
}

return max;
};

renderRow({ min, max }) {
return item => {
const renderMode = TopN.getRenderMode(min, max);
const key = `${item.id || item.label}`;
const lastValue = getLastValue(item.data);
const formatter = item.tickFormatter || this.props.tickFormatter;
const value = formatter(lastValue);
const width = `${100 * (lastValue / maxValue)}%`;
const backgroundColor = item.color;
const isPositiveValue = lastValue >= 0;

const intervalLength = TopN.calcDomain(renderMode, min, max);
const width = 100 * (Math.abs(lastValue) / intervalLength);

const styles = reactcss(
{
default: {
innerBar: {
width,
backgroundColor,
...TopN.calcInnerBarStyles(renderMode, isPositiveValue),
},
innerBarValue: {
...TopN.calcInnerBarDivStyles(item, width, isPositiveValue),
},
label: {
maxWidth: this.state.labelMaxWidth,
Expand All @@ -92,10 +139,12 @@ export class TopN extends Component {
{item.label}
</td>
<td width="100%" className="tvbVisTopN__bar">
<div className="tvbVisTopN__innerBar" style={styles.innerBar} />
<div className="tvbVisTopN__innerBar" style={styles.innerBar}>
<div style={styles.innerBarValue} />
</div>
</td>
<td className="tvbVisTopN__value" data-test-subj="tsvbTopNValue">
{value}
{formatter(lastValue)}
</td>
</tr>
);
Expand All @@ -104,12 +153,20 @@ export class TopN extends Component {

render() {
if (!this.props.series) return null;
const maxValue = this.props.series.reduce((max, series) => {
const lastValue = getLastValue(series.data);
return lastValue > max ? lastValue : max;
}, 0);

const rows = this.props.series.map(this.renderRow(maxValue));
const intervalSettings = this.props.series.reduce(
(acc, series, index) => {
const value = getLastValue(series.data);

return {
min: !index || value < acc.min ? value : acc.min,
max: !index || value > acc.max ? value : acc.max,
};
},
{ min: undefined, max: undefined }
);

const rows = this.props.series.map(this.renderRow(intervalSettings));
let className = 'tvbVisTopN';
if (this.props.reversed) {
className += ' tvbVisTopN--reversed';
Expand Down

0 comments on commit bf9c86f

Please sign in to comment.