Show bucket size for Time Series Visual Builder on X-Axis (#11639)

* Adding seconds to the timeseries tooltip

* Adding x-axis label to show the bucket size
This commit is contained in:
Chris Cowan 2017-05-17 12:08:15 -04:00
parent ee6fa6bcc9
commit 98de700e51
8 changed files with 72 additions and 4 deletions

View file

@ -0,0 +1,16 @@
import { expect } from 'chai';
import { getAxisLabelString } from '../get_axis_label_string';
describe('getAxisLabelString(interval)', () => {
it('should return a valid label for 10 seconds', () => {
expect(getAxisLabelString(10000)).to.equal('per 10 seconds');
});
it('should return a valid label for 2 minutes', () => {
expect(getAxisLabelString(120000)).to.equal('per 2 minutes');
});
it('should return a valid label for 2 hour', () => {
expect(getAxisLabelString(7200000)).to.equal('per 2 hours');
});
});

View file

@ -0,0 +1,25 @@
import { relativeOptions } from '../../../../../ui/public/timepicker/relative_options';
import _ from 'lodash';
import moment from 'moment';
const unitLookup = {
s: 'seconds',
m: 'minutes',
h: 'hours',
d: 'days',
w: 'weeks',
M: 'months',
y: 'years'
};
export function getAxisLabelString(interval) {
const units = _.pluck(_.clone(relativeOptions).reverse(), 'value')
.filter(s => /^[smhdwMy]$/.test(s));
const duration = moment.duration(interval, 'ms');
for (let i = 0; i < units.length; i++) {
const as = duration.as(units[i]);
if (Math.abs(as) > 1) {
const unitValue = Math.round(Math.abs(as));
const unitString = unitLookup[units[i]];
return `per ${unitValue} ${unitString}`;
}
}
}

View file

@ -4,6 +4,7 @@ import _ from 'lodash';
import { Timeseries } from 'plugins/metrics/visualizations';
import color from 'color';
import replaceVars from '../../lib/replace_vars';
import { getAxisLabelString } from '../../lib/get_axis_label_string';
function hasSeperateAxis(row) {
return row.seperate_axis;
@ -76,6 +77,10 @@ function TimeseriesVisualization(props) {
}
});
const interval = series.reduce((currentInterval, item) => {
const seriesInterval = item.data[1][0] - item.data[0][0];
if (!currentInterval || seriesInterval < currentInterval) return seriesInterval;
}, 0);
let axisCount = 1;
if (seriesModel.some(hasSeperateAxis)) {
@ -120,6 +125,9 @@ function TimeseriesVisualization(props) {
if (props.onBrush) props.onBrush(ranges);
}
};
if (interval) {
params.xaxisLabel = getAxisLabelString(interval);
}
const style = { };
const panelBackgroundColor = model.background_color || backgroundColor;
if (panelBackgroundColor) {

View file

@ -102,3 +102,4 @@
color: rgba(255,255,255,0.8);
}
}

View file

@ -1,4 +1,4 @@
import parseInterval from 'ui/utils/parse_interval';
import { parseInterval } from 'ui/utils/parse_interval';
export function validateInterval(timefilter, panel, maxBuckets) {
const { interval } = panel;
const { min, max } = timefilter.getBounds();

View file

@ -130,6 +130,7 @@ class Timeseries extends Component {
show={ this.state.show }
tickFormatter={this.props.tickFormatter}
options={this.props.options}
xaxisLabel={this.props.xaxisLabel}
yaxes={this.props.yaxes} />
</div>
<Legend
@ -162,7 +163,8 @@ Timeseries.propTypes = {
annotations: PropTypes.array,
reversed: PropTypes.bool,
options: PropTypes.object,
tickFormatter: PropTypes.func
tickFormatter: PropTypes.func,
xaxisLabel: PropTypes.string
};
export default Timeseries;

View file

@ -172,7 +172,7 @@ class TimeseriesChart extends Component {
<div style={styles.text}>{ item.series.label }</div>
<div style={styles.value}>{ formatter(value) }</div>
</div>
<div style={styles.date}>{ moment(item.datapoint[0]).format('lll') }</div>
<div style={styles.date}>{ moment(item.datapoint[0]).format('ll LTS') }</div>
</div>
<i className="fa fa-caret-right" style={styles.rightCaret}></i>
</div>
@ -197,12 +197,17 @@ class TimeseriesChart extends Component {
};
const annotations = this.state.annotations.map(this.renderAnnotations);
let axisLabelClass = 'rhythm_chart__axis-label';
if (this.props.reversed) {
axisLabelClass += ' reversed';
}
return (
<div ref={(el) => this.container = el} className="rhythm_chart__timeseries-container">
{ tooltip }
{ annotations }
<FlotChart {...params}/>
<div className={axisLabelClass}>{this.props.xaxisLabel}</div>
</div>
);
}
@ -221,6 +226,7 @@ TimeseriesChart.propTypes = {
show: PropTypes.array,
tickFormatter: PropTypes.func,
yaxes: PropTypes.array,
xaxisLabel: PropTypes.string
};
export default TimeseriesChart;

View file

@ -118,10 +118,20 @@
.rhythm_chart__timeseries-container {
position: relative;
display: flex;
row-direction: column;
flex-direction: column;
flex: 1 0 auto;
}
.rhythm_chart__axis-label {
font-size: 0.8em;
color: rgba(0,0,0,0.4);
text-align: center;
min-height: 1.2em;
&.reversed {
color: rgba(255,255,255,0.6);
}
}
.annotation {
position: absolute;
display: flex;