Skip to content

Commit

Permalink
[TSVB] Greater Than or Equal to Interval Pattern (#13872)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
simianhacker committed Sep 26, 2017
1 parent 60ee437 commit 7178b38
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/core_plugins/metrics/common/interval_regexp.js
Original file line number Diff line number Diff line change
@@ -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('|') + ')$');

Original file line number Diff line number Diff line change
Expand Up @@ -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')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
17 changes: 10 additions & 7 deletions src/core_plugins/metrics/public/lib/validate_interval.js
Original file line number Diff line number Diff line change
@@ -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.`);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});

});
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit 7178b38

Please sign in to comment.