[TSVB] Greater Than or Equal to Interval Pattern (#13872)

* Create new interval pattern for specifying greater than or equal to a bucket size

* Updating label to add >=1m example

* Adding test case for gteAutoMatch
This commit is contained in:
Chris Cowan 2017-09-26 09:37:40 -07:00 committed by GitHub
parent 42f2a19f64
commit 893b3990ac
6 changed files with 44 additions and 10 deletions

View file

@ -0,0 +1,4 @@
import dateMath from '@elastic/datemath';
export const GTE_INTERVAL_RE = new RegExp(`^>=([\\d\\.]*\\s*(${dateMath.units.join('|')}))$`);
export const INTERVAL_STRING_RE = new RegExp('^([0-9\\.]*)\\s*(' + dateMath.units.join('|') + ')$');

View file

@ -51,7 +51,7 @@ export const IndexPattern = props => {
/>
</div>
<label className="vis_editor__label" htmlFor={htmlId('interval')}>
Interval (auto, 1m, 1d, 1w, 1y)
Interval (auto, 1m, 1d, 1w, 1y, &gt;=1m)
</label>
<input
id={htmlId('interval')}

View file

@ -10,7 +10,6 @@ const MetricsRequestHandlerProvider = function (Private, Notifier, config, timef
name: 'metrics',
handler: function (vis /*, appState, uiState, queryFilter*/) {
const timezone = Private(timezoneProvider)();
return new Promise((resolve) => {
const panel = vis.params;
if (panel && panel.id) {

View file

@ -1,16 +1,19 @@
import { parseInterval } from 'ui/utils/parse_interval';
import { GTE_INTERVAL_RE } from '../../common/interval_regexp';
export function validateInterval(timefilter, panel, maxBuckets) {
const { interval } = panel;
const { min, max } = timefilter.getBounds();
// No need to check auto it will return around 100
if (!interval) return;
if (interval === 'auto') return;
const greaterThanMatch = interval.match(GTE_INTERVAL_RE);
if (greaterThanMatch) return;
const duration = parseInterval(interval);
if (!duration) {
throw new Error(`Invalid interval: ${interval} is not a valid interval`);
}
const span = max.valueOf() - min.valueOf();
const buckets = Math.floor(span / duration.asMilliseconds());
if (buckets > maxBuckets) {
throw new Error(`Max buckets exceeded: ${buckets} is greater than ${maxBuckets}, try a larger time interval in the panel options.`);
if (duration) {
const span = max.valueOf() - min.valueOf();
const buckets = Math.floor(span / duration.asMilliseconds());
if (buckets > maxBuckets) {
throw new Error(`Max buckets exceeded: ${buckets} is greater than ${maxBuckets}, try a larger time interval in the panel options.`);
}
}
}

View file

@ -35,4 +35,16 @@ describe('getBucketSize', () => {
expect(result).to.have.property('intervalString', '1d');
});
it('returns overriden buckets (>=2d)', () => {
const result = getBucketSize(req, '>=2d');
expect(result).to.have.property('bucketSize', 86400 * 2);
expect(result).to.have.property('intervalString', '2d');
});
it('returns overriden buckets (>=10s)', () => {
const result = getBucketSize(req, '>=10s');
expect(result).to.have.property('bucketSize', 30);
expect(result).to.have.property('intervalString', '30s');
});
});

View file

@ -1,6 +1,10 @@
import calculateAuto from './calculate_auto';
import moment from 'moment';
import unitToSeconds from './unit_to_seconds';
import {
INTERVAL_STRING_RE,
GTE_INTERVAL_RE
} from '../../../../common/interval_regexp';
export default (req, interval) => {
const from = moment.utc(req.payload.timerange.min);
const to = moment.utc(req.payload.timerange.max);
@ -9,7 +13,19 @@ export default (req, interval) => {
if (bucketSize < 1) bucketSize = 1; // don't go too small
let intervalString = `${bucketSize}s`;
const matches = interval && interval.match(/^([\d]+)([shmdwMy]|ms)$/);
const gteAutoMatch = interval && interval.match(GTE_INTERVAL_RE);
if (gteAutoMatch) {
const intervalStringMatch = gteAutoMatch[1].match(INTERVAL_STRING_RE);
const gteBucketSize = Number(intervalStringMatch[1]) * unitToSeconds(intervalStringMatch[2]);
if (gteBucketSize >= bucketSize) {
return {
bucketSize: gteBucketSize,
intervalString: gteAutoMatch[1]
};
}
}
const matches = interval && interval.match(INTERVAL_STRING_RE);
if (matches) {
bucketSize = Number(matches[1]) * unitToSeconds(matches[2]);
intervalString = interval;