Merge branch 'master' into postgres-query-builder

This commit is contained in:
Sven Klemm 2018-09-03 13:43:58 +02:00
commit de917dfc4d
55 changed files with 324 additions and 313 deletions

View File

@ -27,7 +27,7 @@ Grafana will now persist all long term data in the database. How to configure th
## User sessions
The second thing to consider is how to deal with user sessions and how to configure your load balancer infront of Grafana.
Grafana support two says of storing session data locally on disk or in a database/cache-server.
Grafana supports two ways of storing session data: locally on disk or in a database/cache-server.
If you want to store sessions on disk you can use `sticky sessions` in your load balanacer. If you prefer to store session data in a database/cache-server
you can use any stateless routing strategy in your load balancer (ex round robin or least connections).

View File

@ -105,9 +105,9 @@ export class GrafanaApp {
'react',
];
const module_types = ['controllers', 'directives', 'factories', 'services', 'filters', 'routes'];
const moduleTypes = ['controllers', 'directives', 'factories', 'services', 'filters', 'routes'];
_.each(module_types, type => {
_.each(moduleTypes, type => {
const moduleName = 'grafana.' + type;
this.useModule(angular.module(moduleName, []));
});

View File

@ -84,7 +84,7 @@ function link(scope, elem, attrs) {
// disable depreacation warning
codeEditor.$blockScrolling = Infinity;
// Padding hacks
(<any>codeEditor.renderer).setScrollMargin(15, 15);
(codeEditor.renderer as any).setScrollMargin(15, 15);
codeEditor.renderer.setPadding(10);
setThemeMode();
@ -152,7 +152,7 @@ function link(scope, elem, attrs) {
if (scope.getCompleter()) {
// make copy of array as ace seems to share completers array between instances
const anyEditor = <any>codeEditor;
const anyEditor = codeEditor as any;
anyEditor.completers = anyEditor.completers.slice();
anyEditor.completers.push(scope.getCompleter());
}

View File

@ -11,9 +11,9 @@ export class Settings {
datasources: any;
panels: any;
appSubUrl: string;
window_title_prefix: string;
windowTitlePrefix: string;
buildInfo: BuildInfo;
new_panel_title: string;
newPanelTitle: string;
bootData: any;
externalUserMngLinkUrl: string;
externalUserMngLinkName: string;
@ -51,7 +51,7 @@ export class Settings {
}
}
const bootData = (<any>window).grafanaBootData || { settings: {} };
const bootData = (window as any).grafanaBootData || { settings: {} };
const options = bootData.settings;
options.bootData = bootData;

View File

@ -60,7 +60,7 @@ export class InspectCtrl {
if (keyValue[1].length > 0) {
result.push({
key: keyValue[0],
value: (<any>window).unescape(keyValue[1]),
value: (window as any).unescape(keyValue[1]),
});
}
}

View File

@ -1,4 +1,4 @@
let templates = (<any>require).context('../', true, /\.html$/);
let templates = (require as any).context('../', true, /\.html$/);
templates.keys().forEach(function(key) {
templates(key);
});

View File

@ -12,13 +12,13 @@ export class Analytics {
dataType: 'script',
cache: true,
});
const ga = ((<any>window).ga =
(<any>window).ga ||
const ga = ((window as any).ga =
(window as any).ga ||
function() {
(ga.q = ga.q || []).push(arguments);
});
ga.l = +new Date();
ga('create', (<any>config).googleAnalyticsId, 'auto');
ga('create', (config as any).googleAnalyticsId, 'auto');
ga('set', 'anonymizeIp', true);
return ga;
}
@ -26,7 +26,7 @@ export class Analytics {
init() {
this.$rootScope.$on('$viewContentLoaded', () => {
const track = { page: this.$location.url() };
const ga = (<any>window).ga || this.gaInit();
const ga = (window as any).ga || this.gaInit();
ga('set', track);
ga('send', 'pageview');
});
@ -35,7 +35,7 @@ export class Analytics {
/** @ngInject */
function startAnalytics(googleAnalyticsSrv) {
if ((<any>config).googleAnalyticsId) {
if ((config as any).googleAnalyticsId) {
googleAnalyticsSrv.init();
}
}

View File

@ -562,5 +562,5 @@ function createCtrlWithStubs(searchResponse: any, tags?: any) {
},
};
return new ManageDashboardsCtrl({}, { getNav: () => {} }, <SearchSrv>searchSrvStub, { isEditor: true });
return new ManageDashboardsCtrl({}, { getNav: () => {} }, searchSrvStub as SearchSrv, { isEditor: true });
}

View File

@ -12,7 +12,7 @@ describe('SearchCtrl', () => {
search: (options: any) => {},
getDashboardTags: () => {},
};
const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, <SearchSrv>searchSrvStub);
const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, searchSrvStub as SearchSrv);
describe('Given an empty result', () => {
beforeEach(() => {

View File

@ -2,32 +2,32 @@
function outlineFixer() {
const d: any = document;
const style_element = d.createElement('STYLE');
const dom_events = 'addEventListener' in d;
const styleElement = d.createElement('STYLE');
const domEvents = 'addEventListener' in d;
const add_event_listener = function(type, callback) {
const addEventListener = function(type, callback) {
// Basic cross-browser event handling
if (dom_events) {
if (domEvents) {
d.addEventListener(type, callback);
} else {
d.attachEvent('on' + type, callback);
}
};
const set_css = function(css_text) {
const setCss = function(cssText) {
// Handle setting of <style> element contents in IE8
!!style_element.styleSheet ? (style_element.styleSheet.cssText = css_text) : (style_element.innerHTML = css_text);
!!styleElement.styleSheet ? (styleElement.styleSheet.cssText = cssText) : (styleElement.innerHTML = cssText);
};
d.getElementsByTagName('HEAD')[0].appendChild(style_element);
d.getElementsByTagName('HEAD')[0].appendChild(styleElement);
// Using mousedown instead of mouseover, so that previously focused elements don't lose focus ring on mouse move
add_event_listener('mousedown', function() {
set_css(':focus{outline:0 !important}::-moz-focus-inner{border:0;}');
addEventListener('mousedown', function() {
setCss(':focus{outline:0 !important}::-moz-focus-inner{border:0;}');
});
add_event_listener('keydown', function() {
set_css('');
addEventListener('keydown', function() {
setCss('');
});
}

View File

@ -26,8 +26,8 @@ export function tickStep(start: number, stop: number, count: number): number {
return stop < start ? -step1 : step1;
}
export function getScaledDecimals(decimals, tick_size) {
return decimals - Math.floor(Math.log(tick_size) / Math.LN10);
export function getScaledDecimals(decimals, tickSize) {
return decimals - Math.floor(Math.log(tickSize) / Math.LN10);
}
/**
@ -201,10 +201,10 @@ export function getPrecision(num: number): number {
* Get decimal precision of number stored as a string ("3.14" => 2)
*/
export function getStringPrecision(num: string): number {
const dot_index = num.indexOf('.');
if (dot_index === -1) {
const dotIndex = num.indexOf('.');
if (dotIndex === -1) {
return 0;
} else {
return num.length - dot_index - 1;
return num.length - dotIndex - 1;
}
}

View File

@ -29,6 +29,6 @@ export class SemVersion {
}
export function isVersionGtOrEq(a: string, b: string): boolean {
const a_semver = new SemVersion(a);
return a_semver.isGtOrEq(b);
const aSemver = new SemVersion(a);
return aSemver.isGtOrEq(b);
}

View File

@ -14,33 +14,33 @@ export function makeRegions(annotations, options) {
}
function getRegions(events, range) {
const region_events = _.filter(events, event => {
const regionEvents = _.filter(events, event => {
return event.regionId;
});
let regions = _.groupBy(region_events, 'regionId');
let regions = _.groupBy(regionEvents, 'regionId');
regions = _.compact(
_.map(regions, region_events => {
const region_obj = _.head(region_events);
if (region_events && region_events.length > 1) {
region_obj.timeEnd = region_events[1].time;
region_obj.isRegion = true;
return region_obj;
_.map(regions, regionEvents => {
const regionObj = _.head(regionEvents);
if (regionEvents && regionEvents.length > 1) {
regionObj.timeEnd = regionEvents[1].time;
regionObj.isRegion = true;
return regionObj;
} else {
if (region_events && region_events.length) {
if (regionEvents && regionEvents.length) {
// Don't change proper region object
if (!region_obj.time || !region_obj.timeEnd) {
if (!regionObj.time || !regionObj.timeEnd) {
// This is cut region
if (isStartOfRegion(region_obj)) {
region_obj.timeEnd = range.to.valueOf() - 1;
if (isStartOfRegion(regionObj)) {
regionObj.timeEnd = range.to.valueOf() - 1;
} else {
// Start time = null
region_obj.timeEnd = region_obj.time;
region_obj.time = range.from.valueOf() + 1;
regionObj.timeEnd = regionObj.time;
regionObj.time = range.from.valueOf() + 1;
}
region_obj.isRegion = true;
regionObj.isRegion = true;
}
return region_obj;
return regionObj;
}
}
})

View File

@ -102,7 +102,7 @@ export class DashboardCtrl implements PanelContainer {
}
setWindowTitleAndTheme() {
window.document.title = config.window_title_prefix + this.dashboard.title;
window.document.title = config.windowTitlePrefix + this.dashboard.title;
}
showJsonEditor(evt, options) {

View File

@ -106,7 +106,7 @@ export class DashboardLoaderSrv {
};
/*jshint -W054 */
const script_func = new Function(
const scriptFunc = new Function(
'ARGS',
'kbn',
'dateMath',
@ -119,12 +119,12 @@ export class DashboardLoaderSrv {
'services',
result.data
);
const script_result = script_func(this.$routeParams, kbn, dateMath, _, moment, window, document, $, $, services);
const scriptResult = scriptFunc(this.$routeParams, kbn, dateMath, _, moment, window, document, $, $, services);
// Handle async dashboard scripts
if (_.isFunction(script_result)) {
if (_.isFunction(scriptResult)) {
const deferred = this.$q.defer();
script_result(dashboard => {
scriptResult(dashboard => {
this.$timeout(() => {
deferred.resolve({ data: dashboard });
});
@ -132,7 +132,7 @@ export class DashboardLoaderSrv {
return deferred.promise;
}
return { data: script_result };
return { data: scriptResult };
}
}

View File

@ -94,11 +94,11 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
const utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z'));
// Older browser does not the internationalization API
if (!(<any>window).Intl) {
if (!(window as any).Intl) {
return utcOffset;
}
const dateFormat = (<any>window).Intl.DateTimeFormat();
const dateFormat = (window as any).Intl.DateTimeFormat();
if (!dateFormat.resolvedOptions) {
return utcOffset;
}

View File

@ -271,8 +271,8 @@ describe('given dashboard with row repeat and panel repeat in horizontal directi
});
it('should panels in self row', () => {
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual([
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual([
'row',
'graph',
'graph',
@ -350,8 +350,8 @@ describe('given dashboard with row repeat', function() {
});
it('should not repeat only row', function() {
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']);
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']);
});
it('should set scopedVars for each panel', function() {
@ -399,8 +399,8 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'row', 'row', 'graph']);
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual(['row', 'row', 'row', 'graph']);
expect(dashboard.panels[0].panels).toHaveLength(2);
expect(dashboard.panels[1].panels).toHaveLength(2);
});
@ -441,8 +441,8 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual([
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual([
'row',
'graph',
'graph',
@ -488,7 +488,7 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats();
const panel_ids = _.flattenDeep(
const panelIds = _.flattenDeep(
_.map(dashboard.panels, panel => {
let ids = [];
if (panel.panels && panel.panels.length) {
@ -498,7 +498,7 @@ describe('given dashboard with row repeat', function() {
return ids;
})
);
expect(panel_ids.length).toEqual(_.uniq(panel_ids).length);
expect(panelIds.length).toEqual(_.uniq(panelIds).length);
});
it('should place new panels in proper order', function() {
@ -511,10 +511,10 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']);
const panel_y_positions = _.map(dashboard.panels, p => p.gridPos.y);
expect(panel_y_positions).toEqual([0, 1, 1, 5, 7, 8, 8, 12]);
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']);
const panelYPositions = _.map(dashboard.panels, p => p.gridPos.y);
expect(panelYPositions).toEqual([0, 1, 1, 5, 7, 8, 8, 12]);
});
});
@ -566,8 +566,8 @@ describe('given dashboard with row and panel repeat', () => {
});
it('should repeat row and panels for each row', () => {
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
});
it('should clean up old repeated panels', () => {
@ -592,8 +592,8 @@ describe('given dashboard with row and panel repeat', () => {
dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
const panelTypes = _.map(dashboard.panels, 'type');
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
});
it('should set scopedVars for each row', () => {

View File

@ -4,7 +4,7 @@ import config from 'app/core/config';
import { LinkSrv } from 'app/features/panellinks/link_srv';
describe('ShareModalCtrl', () => {
const ctx = <any>{
const ctx = {
timeSrv: {
timeRange: () => {
return { from: new Date(1000), to: new Date(2000) };
@ -26,9 +26,9 @@ describe('ShareModalCtrl', () => {
templateSrv: {
fillVariableValuesForUrl: () => {},
},
};
} as any;
(<any>window).Intl.DateTimeFormat = () => {
(window as any).Intl.DateTimeFormat = () => {
return {
resolvedOptions: () => {
return { timeZone: 'UTC' };

View File

@ -3,7 +3,7 @@ import { coreModule } from 'app/core/core';
export class ProfileCtrl {
user: any;
old_theme: any;
oldTheme: any;
teams: any = [];
orgs: any = [];
userForm: any;
@ -54,7 +54,7 @@ export class ProfileCtrl {
this.backendSrv.put('/api/user/', this.user).then(() => {
this.contextSrv.user.name = this.user.name || this.user.login;
if (this.old_theme !== this.user.theme) {
if (this.oldTheme !== this.user.theme) {
window.location.href = config.appSubUrl + this.$location.path();
}
});

View File

@ -4,8 +4,8 @@ import { Variable, assignModelProperties, variableTypes } from './variable';
export class IntervalVariable implements Variable {
name: string;
auto_count: number;
auto_min: number;
auto_count: number; // tslint:disable-line variable-name
auto_min: number; // tslint:disable-line variable-name
options: any;
auto: boolean;
query: string;

View File

@ -4,7 +4,7 @@ import moment from 'moment';
import $q from 'q';
describe('VariableSrv', function(this: any) {
const ctx = <any>{
const ctx = {
datasourceSrv: {},
timeSrv: {
timeRange: () => {},
@ -29,7 +29,7 @@ describe('VariableSrv', function(this: any) {
$location: {
search: () => {},
},
};
} as any;
function describeUpdateVariable(desc, fn) {
describe(desc, () => {

View File

@ -17,12 +17,12 @@ describe('VariableSrv init', function(this: any) {
}),
};
const $injector = <any>{};
const $injector = {} as any;
const $rootscope = {
$on: () => {},
};
let ctx = <any>{};
let ctx = {} as any;
function describeInitScenario(desc, fn) {
describe(desc, () => {

View File

@ -25,10 +25,10 @@ describe('CloudWatchDatasource', function() {
},
};
const backendSrv = {};
const ctx = <any>{
const ctx = {
backendSrv,
templateSrv,
};
} as any;
beforeEach(() => {
ctx.ds = new CloudWatchDatasource(instanceSettings, {}, backendSrv, templateSrv, timeSrv);

View File

@ -57,9 +57,9 @@ export class ElasticDatasource {
private get(url) {
const range = this.timeSrv.timeRange();
const index_list = this.indexPattern.getIndexList(range.from.valueOf(), range.to.valueOf());
if (_.isArray(index_list) && index_list.length) {
return this.request('GET', index_list[0] + url).then(function(results) {
const indexList = this.indexPattern.getIndexList(range.from.valueOf(), range.to.valueOf());
if (_.isArray(indexList) && indexList.length) {
return this.request('GET', indexList[0] + url).then(function(results) {
results.data.$$config = results.config;
return results.data;
});
@ -229,15 +229,15 @@ export class ElasticDatasource {
}
getQueryHeader(searchType, timeFrom, timeTo) {
const query_header: any = {
const queryHeader: any = {
search_type: searchType,
ignore_unavailable: true,
index: this.indexPattern.getIndexList(timeFrom, timeTo),
};
if (this.esVersion >= 56) {
query_header['max_concurrent_shard_requests'] = this.maxConcurrentShardRequests;
queryHeader['max_concurrent_shard_requests'] = this.maxConcurrentShardRequests;
}
return angular.toJson(query_header);
return angular.toJson(queryHeader);
}
query(options) {

View File

@ -67,8 +67,8 @@ export class ElasticMetricAggCtrl {
}
switch ($scope.agg.type) {
case 'cardinality': {
const precision_threshold = $scope.agg.settings.precision_threshold || '';
$scope.settingsLinkText = 'Precision threshold: ' + precision_threshold;
const precisionThreshold = $scope.agg.settings.precision_threshold || '';
$scope.settingsLinkText = 'Precision threshold: ' + precisionThreshold;
break;
}
case 'percentiles': {

View File

@ -33,10 +33,10 @@ describe('ElasticDatasource', function(this: any) {
}),
};
const ctx = <any>{
const ctx = {
$rootScope,
backendSrv,
};
} as any;
function createDatasource(instanceSettings) {
instanceSettings.jsonData = instanceSettings.jsonData || {};

View File

@ -19,12 +19,12 @@ describe('ElasticQueryBuilder', () => {
});
it('with defaults on es5.x', () => {
const builder_5x = new ElasticQueryBuilder({
const builder5x = new ElasticQueryBuilder({
timeField: '@timestamp',
esVersion: 5,
});
const query = builder_5x.build({
const query = builder5x.build({
metrics: [{ type: 'Count', id: '0' }],
timeField: '@timestamp',
bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '1' }],
@ -134,11 +134,11 @@ describe('ElasticQueryBuilder', () => {
});
it('with filters aggs on es5.x', () => {
const builder_5x = new ElasticQueryBuilder({
const builder5x = new ElasticQueryBuilder({
timeField: '@timestamp',
esVersion: 5,
});
const query = builder_5x.build({
const query = builder5x.build({
metrics: [{ type: 'count', id: '1' }],
timeField: '@timestamp',
bucketAggs: [

View File

@ -490,8 +490,8 @@ export function GraphiteDatasource(this: any, instanceSettings, $q, backendSrv,
this._seriesRefLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
this.buildGraphiteParams = function(options, scopedVars) {
const graphite_options = ['from', 'until', 'rawData', 'format', 'maxDataPoints', 'cacheTimeout'];
const clean_options = [],
const graphiteOptions = ['from', 'until', 'rawData', 'format', 'maxDataPoints', 'cacheTimeout'];
const cleanOptions = [],
targets = {};
let target, targetValue, i;
const regex = /\#([A-Z])/g;
@ -535,16 +535,16 @@ export function GraphiteDatasource(this: any, instanceSettings, $q, backendSrv,
if (!target.hide) {
hasTargets = true;
clean_options.push('target=' + encodeURIComponent(targetValue));
cleanOptions.push('target=' + encodeURIComponent(targetValue));
}
}
_.each(options, function(value, key) {
if (_.indexOf(graphite_options, key) === -1) {
if (_.indexOf(graphiteOptions, key) === -1) {
return;
}
if (value) {
clean_options.push(key + '=' + encodeURIComponent(value));
cleanOptions.push(key + '=' + encodeURIComponent(value));
}
});
@ -552,7 +552,7 @@ export function GraphiteDatasource(this: any, instanceSettings, $q, backendSrv,
return [];
}
return clean_options;
return cleanOptions;
};
}

View File

@ -3,7 +3,7 @@ import gfunc from '../gfunc';
import { GraphiteQueryCtrl } from '../query_ctrl';
describe('GraphiteQueryCtrl', () => {
const ctx = <any>{
const ctx = {
datasource: {
metricFindQuery: jest.fn(() => Promise.resolve([])),
getFuncDefs: jest.fn(() => Promise.resolve(gfunc.getFuncDefs('1.0'))),
@ -15,7 +15,7 @@ describe('GraphiteQueryCtrl', () => {
panelCtrl: {
refresh: jest.fn(),
},
};
} as any;
ctx.panelCtrl.panel = {
targets: [ctx.target],

View File

@ -3,7 +3,7 @@ import { uiSegmentSrv } from 'app/core/services/segment_srv';
import { InfluxQueryCtrl } from '../query_ctrl';
describe('InfluxDBQueryCtrl', () => {
const ctx = <any>{};
const ctx = {} as any;
beforeEach(() => {
InfluxQueryCtrl.prototype.datasource = {

View File

@ -9,9 +9,9 @@ describe('MySQLDatasource', function() {
replace: jest.fn(text => text),
};
const ctx = <any>{
const ctx = {
backendSrv,
};
} as any;
beforeEach(() => {
ctx.ds = new MysqlDatasource(instanceSettings, backendSrv, {}, templateSrv);

View File

@ -277,35 +277,35 @@ export default class OpenTsDatasource {
});
};
const metrics_regex = /metrics\((.*)\)/;
const tag_names_regex = /tag_names\((.*)\)/;
const tag_values_regex = /tag_values\((.*?),\s?(.*)\)/;
const tag_names_suggest_regex = /suggest_tagk\((.*)\)/;
const tag_values_suggest_regex = /suggest_tagv\((.*)\)/;
const metricsRegex = /metrics\((.*)\)/;
const tagNamesRegex = /tag_names\((.*)\)/;
const tagValuesRegex = /tag_values\((.*?),\s?(.*)\)/;
const tagNamesSuggestRegex = /suggest_tagk\((.*)\)/;
const tagValuesSuggestRegex = /suggest_tagv\((.*)\)/;
const metrics_query = interpolated.match(metrics_regex);
if (metrics_query) {
return this._performSuggestQuery(metrics_query[1], 'metrics').then(responseTransform);
const metricsQuery = interpolated.match(metricsRegex);
if (metricsQuery) {
return this._performSuggestQuery(metricsQuery[1], 'metrics').then(responseTransform);
}
const tag_names_query = interpolated.match(tag_names_regex);
if (tag_names_query) {
return this._performMetricKeyLookup(tag_names_query[1]).then(responseTransform);
const tagNamesQuery = interpolated.match(tagNamesRegex);
if (tagNamesQuery) {
return this._performMetricKeyLookup(tagNamesQuery[1]).then(responseTransform);
}
const tag_values_query = interpolated.match(tag_values_regex);
if (tag_values_query) {
return this._performMetricKeyValueLookup(tag_values_query[1], tag_values_query[2]).then(responseTransform);
const tagValuesQuery = interpolated.match(tagValuesRegex);
if (tagValuesQuery) {
return this._performMetricKeyValueLookup(tagValuesQuery[1], tagValuesQuery[2]).then(responseTransform);
}
const tag_names_suggest_query = interpolated.match(tag_names_suggest_regex);
if (tag_names_suggest_query) {
return this._performSuggestQuery(tag_names_suggest_query[1], 'tagk').then(responseTransform);
const tagNamesSuggestQuery = interpolated.match(tagNamesSuggestRegex);
if (tagNamesSuggestQuery) {
return this._performSuggestQuery(tagNamesSuggestQuery[1], 'tagk').then(responseTransform);
}
const tag_values_suggest_query = interpolated.match(tag_values_suggest_regex);
if (tag_values_suggest_query) {
return this._performSuggestQuery(tag_values_suggest_query[1], 'tagv').then(responseTransform);
const tagValuesSuggestQuery = interpolated.match(tagValuesSuggestRegex);
if (tagValuesSuggestQuery) {
return this._performSuggestQuery(tagValuesSuggestQuery[1], 'tagv').then(responseTransform);
}
return this.$q.when([]);
@ -440,9 +440,9 @@ export default class OpenTsDatasource {
if (target.filters && target.filters.length > 0) {
query.filters = angular.copy(target.filters);
if (query.filters) {
for (const filter_key in query.filters) {
query.filters[filter_key].filter = this.templateSrv.replace(
query.filters[filter_key].filter,
for (const filterKey in query.filters) {
query.filters[filterKey].filter = this.templateSrv.replace(
query.filters[filterKey].filter,
options.scopedVars,
'pipe'
);
@ -451,8 +451,8 @@ export default class OpenTsDatasource {
} else {
query.tags = angular.copy(target.tags);
if (query.tags) {
for (const tag_key in query.tags) {
query.tags[tag_key] = this.templateSrv.replace(query.tags[tag_key], options.scopedVars, 'pipe');
for (const tagKey in query.tags) {
query.tags[tagKey] = this.templateSrv.replace(query.tags[tagKey], options.scopedVars, 'pipe');
}
}
}

View File

@ -2,13 +2,13 @@ import OpenTsDatasource from '../datasource';
import $q from 'q';
describe('opentsdb', () => {
const ctx = <any>{
const ctx = {
backendSrv: {},
ds: {},
templateSrv: {
replace: str => str,
},
};
} as any;
const instanceSettings = { url: '', jsonData: { tsdbVersion: 1 } };
beforeEach(() => {

View File

@ -1,14 +1,14 @@
import { OpenTsQueryCtrl } from '../query_ctrl';
describe('OpenTsQueryCtrl', () => {
const ctx = <any>{
const ctx = {
target: { target: '' },
datasource: {
tsdbVersion: '',
getAggregators: () => Promise.resolve([]),
getFilterTypes: () => Promise.resolve([]),
},
};
} as any;
ctx.panelCtrl = {
panel: {

View File

@ -13,7 +13,7 @@ describe('PostgreSQLDatasource', function() {
from: moment.utc('2018-04-25 10:00'),
to: moment.utc('2018-04-25 11:00'),
};
const ctx = <any>{
const ctx = {
backendSrv,
timeSrvMock: {
timeRange: () => ({
@ -22,7 +22,7 @@ describe('PostgreSQLDatasource', function() {
raw: raw,
}),
},
};
} as any;
beforeEach(() => {
ctx.ds = new PostgresDatasource(instanceSettings, backendSrv, {}, templateSrv, ctx.timeSrvMock);

View File

@ -12,27 +12,27 @@ export default class PrometheusMetricFindQuery {
}
process() {
const label_values_regex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)\s*$/;
const metric_names_regex = /^metrics\((.+)\)\s*$/;
const query_result_regex = /^query_result\((.+)\)\s*$/;
const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)\s*$/;
const metricNamesRegex = /^metrics\((.+)\)\s*$/;
const queryResultRegex = /^query_result\((.+)\)\s*$/;
const label_values_query = this.query.match(label_values_regex);
if (label_values_query) {
if (label_values_query[1]) {
return this.labelValuesQuery(label_values_query[2], label_values_query[1]);
const labelValuesQuery = this.query.match(labelValuesRegex);
if (labelValuesQuery) {
if (labelValuesQuery[1]) {
return this.labelValuesQuery(labelValuesQuery[2], labelValuesQuery[1]);
} else {
return this.labelValuesQuery(label_values_query[2], null);
return this.labelValuesQuery(labelValuesQuery[2], null);
}
}
const metric_names_query = this.query.match(metric_names_regex);
if (metric_names_query) {
return this.metricNameQuery(metric_names_query[1]);
const metricNamesQuery = this.query.match(metricNamesRegex);
if (metricNamesQuery) {
return this.metricNameQuery(metricNamesQuery[1]);
}
const query_result_query = this.query.match(query_result_regex);
if (query_result_query) {
return this.queryResultQuery(query_result_query[1]);
const queryResultQuery = this.query.match(queryResultRegex);
if (queryResultQuery) {
return this.queryResultQuery(queryResultQuery[1]);
}
// if query contains full metric name, return metric name and label list

View File

@ -45,9 +45,9 @@ export class ResultTransformer {
}
for (const value of metricData.values) {
let dp_value = parseFloat(value[1]);
if (_.isNaN(dp_value)) {
dp_value = null;
let dpValue = parseFloat(value[1]);
if (_.isNaN(dpValue)) {
dpValue = null;
}
const timestamp = parseFloat(value[0]) * 1000;
@ -55,7 +55,7 @@ export class ResultTransformer {
dps.push([null, t]);
}
baseTimestamp = timestamp + stepMs;
dps.push([dp_value, timestamp]);
dps.push([dpValue, timestamp]);
}
const endTimestamp = end * 1000;

View File

@ -15,7 +15,7 @@ describe('Prometheus editor completer', function() {
const editor = {};
const backendSrv = <BackendSrv>{};
const backendSrv = {} as BackendSrv;
const datasourceStub = new PrometheusDatasource({}, {}, backendSrv, {}, {});
datasourceStub.performInstantQuery = jest.fn(() =>

View File

@ -385,7 +385,7 @@ const HOUR = 60 * MINUTE;
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => moment(hours * HOUR + minutes * MINUTE + seconds * SECOND);
const ctx = <any>{};
const ctx = {} as any;
const instanceSettings = {
url: 'proxied',
directUrl: 'direct',
@ -393,9 +393,9 @@ const instanceSettings = {
password: 'mupp',
jsonData: { httpMethod: 'GET' },
};
const backendSrv = <any>{
const backendSrv = {
datasourceRequest: jest.fn(),
};
} as any;
const templateSrv = {
replace: jest.fn(str => str),
@ -435,7 +435,7 @@ describe('PrometheusDatasource', () => {
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
@ -485,7 +485,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
@ -546,7 +546,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
@ -601,7 +601,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.annotationQuery(options).then(function(data) {
results = data;
@ -641,7 +641,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
@ -678,7 +678,7 @@ describe('PrometheusDatasource', () => {
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -694,7 +694,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=1';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -715,7 +715,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -732,7 +732,7 @@ describe('PrometheusDatasource', () => {
const start = 60 * 60;
const urlExpected = 'proxied/api/v1/query_range?query=test&start=' + start + '&end=' + end + '&step=2';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -754,7 +754,7 @@ describe('PrometheusDatasource', () => {
// times get rounded up to interval
const urlExpected = 'proxied/api/v1/query_range?query=test&start=50&end=450&step=50';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -775,7 +775,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=60&end=420&step=15';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -797,7 +797,7 @@ describe('PrometheusDatasource', () => {
// times get aligned to interval
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=0&end=500&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -819,7 +819,7 @@ describe('PrometheusDatasource', () => {
const start = 0;
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -841,7 +841,7 @@ describe('PrometheusDatasource', () => {
const start = 0;
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=60';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -884,7 +884,7 @@ describe('PrometheusDatasource', () => {
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -923,7 +923,7 @@ describe('PrometheusDatasource', () => {
'&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -963,7 +963,7 @@ describe('PrometheusDatasource', () => {
'&start=0&end=500&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -1009,7 +1009,7 @@ describe('PrometheusDatasource', () => {
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -1049,7 +1049,7 @@ describe('PrometheusDatasource', () => {
'&start=60&end=420&step=15';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -1094,7 +1094,7 @@ describe('PrometheusDatasource', () => {
'&step=60';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
@ -1155,7 +1155,7 @@ describe('PrometheusDatasource for POST', () => {
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});

View File

@ -484,22 +484,22 @@ class GraphElement {
const defaultTicks = this.panelWidth / 50;
if (this.data.length && bucketSize) {
const tick_values = [];
const tickValues = [];
for (const d of this.data) {
for (const point of d.data) {
tick_values[point[0]] = true;
tickValues[point[0]] = true;
}
}
ticks = Object.keys(tick_values).map(v => Number(v));
ticks = Object.keys(tickValues).map(v => Number(v));
min = _.min(ticks);
max = _.max(ticks);
// Adjust tick step
let tickStep = bucketSize;
let ticks_num = Math.floor((max - min) / tickStep);
while (ticks_num > defaultTicks) {
let ticksNum = Math.floor((max - min) / tickStep);
while (ticksNum > defaultTicks) {
tickStep = tickStep * 2;
ticks_num = Math.ceil((max - min) / tickStep);
ticksNum = Math.ceil((max - min) / tickStep);
}
// Expand ticks for pretty view

View File

@ -62,7 +62,7 @@ export default function GraphTooltip(this: any, elem, dashboard, scope, getSerie
let results: any = [[], [], []];
//now we know the current X (j) position for X and Y values
let last_value = 0; //needed for stacked values
let lastValue = 0; //needed for stacked values
let minDistance, minTime;
@ -106,8 +106,8 @@ export default function GraphTooltip(this: any, elem, dashboard, scope, getSerie
} else if (!series.stack) {
value = series.data[hoverIndex][1];
} else {
last_value += series.data[hoverIndex][1];
value = last_value;
lastValue += series.data[hoverIndex][1];
value = lastValue;
}
} else {
value = series.data[hoverIndex][1];

View File

@ -47,12 +47,12 @@ export function convertValuesToHistogram(values: number[], bucketSize: number, m
histogram[bound] = histogram[bound] + 1;
}
const histogam_series = _.map(histogram, (count, bound) => {
const histogamSeries = _.map(histogram, (count, bound) => {
return [Number(bound), count];
});
// Sort by Y axis values
return _.sortBy(histogam_series, point => point[0]);
return _.sortBy(histogamSeries, point => point[0]);
}
/**

View File

@ -28,7 +28,7 @@ import moment from 'moment';
import $ from 'jquery';
import { graphDirective } from '../graph';
const ctx = <any>{};
const ctx = {} as any;
let ctrl;
const scope = {
ctrl: {},
@ -47,7 +47,7 @@ describe('grafanaGraph', function() {
lightTheme: false,
},
};
GraphCtrl.prototype = <any>{
GraphCtrl.prototype = {
...MetricsPanelCtrl.prototype,
...PanelCtrl.prototype,
...GraphCtrl.prototype,
@ -88,7 +88,7 @@ describe('grafanaGraph', function() {
from: moment([2015, 1, 1, 10]),
to: moment([2015, 1, 1, 22]),
},
};
} as any;
ctx.data = [];
ctx.data.push(

View File

@ -30,7 +30,7 @@ describe('GraphCtrl', () => {
},
};
const ctx = <any>{};
const ctx = {} as any;
beforeEach(() => {
ctx.ctrl = new GraphCtrl(scope, injector, {});

View File

@ -97,7 +97,7 @@ const colorSchemes = [
{ name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' },
];
const ds_support_histogram_sort = ['prometheus', 'elasticsearch'];
const dsSupportHistogramSort = ['prometheus', 'elasticsearch'];
export class HeatmapCtrl extends MetricsPanelCtrl {
static templateUrl = 'module.html';
@ -221,7 +221,7 @@ export class HeatmapCtrl extends MetricsPanelCtrl {
let xBucketSize, yBucketSize, bucketsData, tsBuckets;
// Try to sort series by bucket bound, if datasource doesn't do it.
if (!_.includes(ds_support_histogram_sort, panelDatasource)) {
if (!_.includes(dsSupportHistogramSort, panelDatasource)) {
this.series.sort(sortSeriesByLabel);
}

View File

@ -253,16 +253,16 @@ function pushToXBuckets(buckets, point, bucketNum, seriesName) {
}
// Add series name to point for future identification
const point_ext = _.concat(point, seriesName);
const pointExt = _.concat(point, seriesName);
if (buckets[bucketNum] && buckets[bucketNum].values) {
buckets[bucketNum].values.push(value);
buckets[bucketNum].points.push(point_ext);
buckets[bucketNum].points.push(pointExt);
} else {
buckets[bucketNum] = {
x: bucketNum,
values: [value],
points: [point_ext],
points: [pointExt],
};
}
}
@ -335,17 +335,17 @@ function getLogScaleBucketBounds(value, yBucketSplitFactor, logBase) {
return { bottom: 0, top: 0 };
}
const value_log = logp(value, logBase);
const valueLog = logp(value, logBase);
let pow, powTop;
if (yBucketSplitFactor === 1 || !yBucketSplitFactor) {
pow = Math.floor(value_log);
pow = Math.floor(valueLog);
powTop = pow + 1;
} else {
const additional_bucket_size = 1 / yBucketSplitFactor;
let additional_log = value_log - Math.floor(value_log);
additional_log = Math.floor(additional_log / additional_bucket_size) * additional_bucket_size;
pow = Math.floor(value_log) + additional_log;
powTop = pow + additional_bucket_size;
const additionalBucketSize = 1 / yBucketSplitFactor;
let additionalLog = valueLog - Math.floor(valueLog);
additionalLog = Math.floor(additionalLog / additionalBucketSize) * additionalBucketSize;
pow = Math.floor(valueLog) + additionalLog;
powTop = pow + additionalBucketSize;
}
bottom = Math.pow(logBase, pow);
top = Math.pow(logBase, powTop);
@ -427,46 +427,46 @@ function getDistance(a: number, b: number, logBase = 1): number {
* @param objB
*/
function isHeatmapDataEqual(objA: any, objB: any): boolean {
let is_eql = !emptyXOR(objA, objB);
let isEql = !emptyXOR(objA, objB);
_.forEach(objA, (xBucket: XBucket, x) => {
if (objB[x]) {
if (emptyXOR(xBucket.buckets, objB[x].buckets)) {
is_eql = false;
isEql = false;
return false;
}
_.forEach(xBucket.buckets, (yBucket: YBucket, y) => {
if (objB[x].buckets && objB[x].buckets[y]) {
if (objB[x].buckets[y].values) {
is_eql = _.isEqual(_.sortBy(yBucket.values), _.sortBy(objB[x].buckets[y].values));
if (!is_eql) {
isEql = _.isEqual(_.sortBy(yBucket.values), _.sortBy(objB[x].buckets[y].values));
if (!isEql) {
return false;
} else {
return true;
}
} else {
is_eql = false;
isEql = false;
return false;
}
} else {
is_eql = false;
isEql = false;
return false;
}
});
if (!is_eql) {
if (!isEql) {
return false;
} else {
return true;
}
} else {
is_eql = false;
isEql = false;
return false;
}
});
return is_eql;
return isEql;
}
function emptyXOR(foo: any, bar: any): boolean {

View File

@ -117,23 +117,23 @@ export class HeatmapRenderer {
}
getYAxisWidth(elem) {
const axis_text = elem.selectAll('.axis-y text').nodes();
const max_text_width = _.max(
_.map(axis_text, text => {
const axisText = elem.selectAll('.axis-y text').nodes();
const maxTextWidth = _.max(
_.map(axisText, text => {
// Use SVG getBBox method
return text.getBBox().width;
})
);
return max_text_width;
return maxTextWidth;
}
getXAxisHeight(elem) {
const axis_line = elem.select('.axis-x line');
if (!axis_line.empty()) {
const axis_line_position = parseFloat(elem.select('.axis-x line').attr('y2'));
const canvas_width = parseFloat(elem.attr('height'));
return canvas_width - axis_line_position;
const axisLine = elem.select('.axis-x line');
if (!axisLine.empty()) {
const axisLinePosition = parseFloat(elem.select('.axis-x line').attr('y2'));
const canvasWidth = parseFloat(elem.attr('height'));
return canvasWidth - axisLinePosition;
} else {
// Default height
return 30;
@ -180,42 +180,42 @@ export class HeatmapRenderer {
addYAxis() {
let ticks = Math.ceil(this.chartHeight / DEFAULT_Y_TICK_SIZE_PX);
let tick_interval = ticksUtils.tickStep(this.data.heatmapStats.min, this.data.heatmapStats.max, ticks);
let { y_min, y_max } = this.wideYAxisRange(this.data.heatmapStats.min, this.data.heatmapStats.max, tick_interval);
let tickInterval = ticksUtils.tickStep(this.data.heatmapStats.min, this.data.heatmapStats.max, ticks);
let { yMin, yMax } = this.wideYAxisRange(this.data.heatmapStats.min, this.data.heatmapStats.max, tickInterval);
// Rewrite min and max if it have been set explicitly
y_min = this.panel.yAxis.min !== null ? this.panel.yAxis.min : y_min;
y_max = this.panel.yAxis.max !== null ? this.panel.yAxis.max : y_max;
yMin = this.panel.yAxis.min !== null ? this.panel.yAxis.min : yMin;
yMax = this.panel.yAxis.max !== null ? this.panel.yAxis.max : yMax;
// Adjust ticks after Y range widening
tick_interval = ticksUtils.tickStep(y_min, y_max, ticks);
ticks = Math.ceil((y_max - y_min) / tick_interval);
tickInterval = ticksUtils.tickStep(yMin, yMax, ticks);
ticks = Math.ceil((yMax - yMin) / tickInterval);
const decimalsAuto = ticksUtils.getPrecision(tick_interval);
const decimalsAuto = ticksUtils.getPrecision(tickInterval);
let decimals = this.panel.yAxis.decimals === null ? decimalsAuto : this.panel.yAxis.decimals;
// Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js)
const flot_tick_size = ticksUtils.getFlotTickSize(y_min, y_max, ticks, decimalsAuto);
const scaledDecimals = ticksUtils.getScaledDecimals(decimals, flot_tick_size);
const flotTickSize = ticksUtils.getFlotTickSize(yMin, yMax, ticks, decimalsAuto);
const scaledDecimals = ticksUtils.getScaledDecimals(decimals, flotTickSize);
this.ctrl.decimals = decimals;
this.ctrl.scaledDecimals = scaledDecimals;
// Set default Y min and max if no data
if (_.isEmpty(this.data.buckets)) {
y_max = 1;
y_min = -1;
yMax = 1;
yMin = -1;
ticks = 3;
decimals = 1;
}
this.data.yAxis = {
min: y_min,
max: y_max,
min: yMin,
max: yMax,
ticks: ticks,
};
this.scope.yScale = this.yScale = d3
.scaleLinear()
.domain([y_min, y_max])
.domain([yMin, yMax])
.range([this.chartHeight, 0]);
const yAxis = d3
@ -245,67 +245,67 @@ export class HeatmapRenderer {
// Wide Y values range and anjust to bucket size
wideYAxisRange(min, max, tickInterval) {
const y_widing = (max * (this.dataRangeWidingFactor - 1) - min * (this.dataRangeWidingFactor - 1)) / 2;
let y_min, y_max;
const yWiding = (max * (this.dataRangeWidingFactor - 1) - min * (this.dataRangeWidingFactor - 1)) / 2;
let yMin, yMax;
if (tickInterval === 0) {
y_max = max * this.dataRangeWidingFactor;
y_min = min - min * (this.dataRangeWidingFactor - 1);
tickInterval = (y_max - y_min) / 2;
yMax = max * this.dataRangeWidingFactor;
yMin = min - min * (this.dataRangeWidingFactor - 1);
tickInterval = (yMax - yMin) / 2;
} else {
y_max = Math.ceil((max + y_widing) / tickInterval) * tickInterval;
y_min = Math.floor((min - y_widing) / tickInterval) * tickInterval;
yMax = Math.ceil((max + yWiding) / tickInterval) * tickInterval;
yMin = Math.floor((min - yWiding) / tickInterval) * tickInterval;
}
// Don't wide axis below 0 if all values are positive
if (min >= 0 && y_min < 0) {
y_min = 0;
if (min >= 0 && yMin < 0) {
yMin = 0;
}
return { y_min, y_max };
return { yMin, yMax };
}
addLogYAxis() {
const log_base = this.panel.yAxis.logBase;
let { y_min, y_max } = this.adjustLogRange(this.data.heatmapStats.minLog, this.data.heatmapStats.max, log_base);
const logBase = this.panel.yAxis.logBase;
let { yMin, yMax } = this.adjustLogRange(this.data.heatmapStats.minLog, this.data.heatmapStats.max, logBase);
y_min =
this.panel.yAxis.min && this.panel.yAxis.min !== '0' ? this.adjustLogMin(this.panel.yAxis.min, log_base) : y_min;
y_max = this.panel.yAxis.max !== null ? this.adjustLogMax(this.panel.yAxis.max, log_base) : y_max;
yMin =
this.panel.yAxis.min && this.panel.yAxis.min !== '0' ? this.adjustLogMin(this.panel.yAxis.min, logBase) : yMin;
yMax = this.panel.yAxis.max !== null ? this.adjustLogMax(this.panel.yAxis.max, logBase) : yMax;
// Set default Y min and max if no data
if (_.isEmpty(this.data.buckets)) {
y_max = Math.pow(log_base, 2);
y_min = 1;
yMax = Math.pow(logBase, 2);
yMin = 1;
}
this.scope.yScale = this.yScale = d3
.scaleLog()
.base(this.panel.yAxis.logBase)
.domain([y_min, y_max])
.domain([yMin, yMax])
.range([this.chartHeight, 0]);
const domain = this.yScale.domain();
const tick_values = this.logScaleTickValues(domain, log_base);
const tickValues = this.logScaleTickValues(domain, logBase);
const decimalsAuto = ticksUtils.getPrecision(y_min);
const decimalsAuto = ticksUtils.getPrecision(yMin);
const decimals = this.panel.yAxis.decimals || decimalsAuto;
// Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js)
const flot_tick_size = ticksUtils.getFlotTickSize(y_min, y_max, tick_values.length, decimalsAuto);
const scaledDecimals = ticksUtils.getScaledDecimals(decimals, flot_tick_size);
const flotTickSize = ticksUtils.getFlotTickSize(yMin, yMax, tickValues.length, decimalsAuto);
const scaledDecimals = ticksUtils.getScaledDecimals(decimals, flotTickSize);
this.ctrl.decimals = decimals;
this.ctrl.scaledDecimals = scaledDecimals;
this.data.yAxis = {
min: y_min,
max: y_max,
ticks: tick_values.length,
min: yMin,
max: yMax,
ticks: tickValues.length,
};
const yAxis = d3
.axisLeft(this.yScale)
.tickValues(tick_values)
.tickValues(tickValues)
.tickFormat(this.tickValueFormatter(decimals, scaledDecimals))
.tickSizeInner(0 - this.width)
.tickSizeOuter(0)
@ -322,7 +322,7 @@ export class HeatmapRenderer {
this.heatmap.select('.axis-y').attr('transform', 'translate(' + posX + ',' + posY + ')');
// Set first tick as pseudo 0
if (y_min < 1) {
if (yMin < 1) {
this.heatmap
.select('.axis-y')
.select('.tick text')
@ -344,7 +344,7 @@ export class HeatmapRenderer {
.domain([0, tsBuckets.length - 1])
.range([this.chartHeight, 0]);
const tick_values = _.map(tsBuckets, (b, i) => i);
const tickValues = _.map(tsBuckets, (b, i) => i);
const decimalsAuto = _.max(_.map(tsBuckets, ticksUtils.getStringPrecision));
const decimals = this.panel.yAxis.decimals === null ? decimalsAuto : this.panel.yAxis.decimals;
this.ctrl.decimals = decimals;
@ -364,7 +364,7 @@ export class HeatmapRenderer {
const yAxis = d3
.axisLeft(this.yScale)
.tickValues(tick_values)
.tickValues(tickValues)
.tickFormat(tickFormatter)
.tickSizeInner(0 - this.width)
.tickSizeOuter(0)
@ -389,19 +389,19 @@ export class HeatmapRenderer {
// Adjust data range to log base
adjustLogRange(min, max, logBase) {
let y_min, y_max;
let yMin, yMax;
y_min = this.data.heatmapStats.minLog;
yMin = this.data.heatmapStats.minLog;
if (this.data.heatmapStats.minLog > 1 || !this.data.heatmapStats.minLog) {
y_min = 1;
yMin = 1;
} else {
y_min = this.adjustLogMin(this.data.heatmapStats.minLog, logBase);
yMin = this.adjustLogMin(this.data.heatmapStats.minLog, logBase);
}
// Adjust max Y value to log base
y_max = this.adjustLogMax(this.data.heatmapStats.max, logBase);
yMax = this.adjustLogMax(this.data.heatmapStats.max, logBase);
return { y_min, y_max };
return { yMin, yMax };
}
adjustLogMax(max, base) {
@ -418,17 +418,17 @@ export class HeatmapRenderer {
const tickValues = [];
if (domainMin < 1) {
const under_one_ticks = Math.floor(ticksUtils.logp(domainMin, base));
for (let i = under_one_ticks; i < 0; i++) {
const tick_value = Math.pow(base, i);
tickValues.push(tick_value);
const underOneTicks = Math.floor(ticksUtils.logp(domainMin, base));
for (let i = underOneTicks; i < 0; i++) {
const tickValue = Math.pow(base, i);
tickValues.push(tickValue);
}
}
const ticks = Math.ceil(ticksUtils.logp(domainMax, base));
for (let i = 0; i <= ticks; i++) {
const tick_value = Math.pow(base, i);
tickValues.push(tick_value);
const tickValue = Math.pow(base, i);
tickValues.push(tickValue);
}
return tickValues;
@ -490,7 +490,7 @@ export class HeatmapRenderer {
}
addHeatmapCanvas() {
const heatmap_elem = this.$heatmap[0];
const heatmapElem = this.$heatmap[0];
this.width = Math.floor(this.$heatmap.width()) - this.padding.right;
this.height = Math.floor(this.$heatmap.height()) - this.padding.bottom;
@ -503,7 +503,7 @@ export class HeatmapRenderer {
}
this.heatmap = d3
.select(heatmap_elem)
.select(heatmapElem)
.append('svg')
.attr('width', this.width)
.attr('height', this.height);
@ -514,10 +514,10 @@ export class HeatmapRenderer {
this.addAxes();
if (this.panel.yAxis.logBase !== 1 && this.panel.dataFormat !== 'tsbuckets') {
const log_base = this.panel.yAxis.logBase;
const logBase = this.panel.yAxis.logBase;
const domain = this.yScale.domain();
const tick_values = this.logScaleTickValues(domain, log_base);
this.data.buckets = mergeZeroBuckets(this.data.buckets, _.min(tick_values));
const tickValues = this.logScaleTickValues(domain, logBase);
this.data.buckets = mergeZeroBuckets(this.data.buckets, _.min(tickValues));
}
const cardsData = this.data.cards;
@ -565,9 +565,9 @@ export class HeatmapRenderer {
const color = d3.select(event.target).style('fill');
const highlightColor = d3.color(color).darker(2);
const strokeColor = d3.color(color).brighter(4);
const current_card = d3.select(event.target);
const currentCard = d3.select(event.target);
this.tooltip.originalFillColor = color;
current_card
currentCard
.style('fill', highlightColor.toString())
.style('stroke', strokeColor.toString())
.style('stroke-width', 1);
@ -611,8 +611,8 @@ export class HeatmapRenderer {
let w;
if (this.xScale(d.x) < 0) {
// Cut card left to prevent overlay
const cutted_width = this.xScale(d.x) + this.cardWidth;
w = cutted_width > 0 ? cutted_width : 0;
const cuttedWidth = this.xScale(d.x) + this.cardWidth;
w = cuttedWidth > 0 ? cuttedWidth : 0;
} else if (this.xScale(d.x) + this.cardWidth > this.chartWidth) {
// Cut card right to prevent overlay
w = this.chartWidth - this.xScale(d.x) - this.cardPadding;

View File

@ -2,7 +2,7 @@ import moment from 'moment';
import { HeatmapCtrl } from '../heatmap_ctrl';
describe('HeatmapCtrl', function() {
const ctx = <any>{};
const ctx = {} as any;
const $injector = {
get: () => {},

View File

@ -2,7 +2,7 @@ import { SingleStatCtrl } from '../module';
import moment from 'moment';
describe('SingleStatCtrl', function() {
const ctx = <any>{};
const ctx = {} as any;
const epoch = 1505826363746;
Date.now = () => epoch;

View File

@ -185,7 +185,7 @@ export class TableRenderer {
}
const numericValue = Number(value);
if (numericValue === NaN) {
if (isNaN(numericValue)) {
return;
}
@ -194,11 +194,11 @@ export class TableRenderer {
renderRowVariables(rowIndex) {
const scopedVars = {};
let cell_variable;
let cellVariable;
const row = this.table.rows[rowIndex];
for (let i = 0; i < row.length; i++) {
cell_variable = `__cell_${i}`;
scopedVars[cell_variable] = { value: row[i] };
cellVariable = `__cell_${i}`;
scopedVars[cellVariable] = { value: row[i] };
}
return scopedVars;
}
@ -324,11 +324,11 @@ export class TableRenderer {
for (let y = 0; y < this.table.rows.length; y++) {
const row = this.table.rows[y];
const new_row = [];
const newRow = [];
for (let i = 0; i < this.table.columns.length; i++) {
new_row.push(this.formatColumnValue(i, row[i]));
newRow.push(this.formatColumnValue(i, row[i]));
}
rows.push(new_row);
rows.push(newRow);
}
return {
columns: this.table.columns,

View File

@ -21,7 +21,7 @@ angular.module('grafana.directives', []);
angular.module('grafana.filters', []);
angular.module('grafana.routes', ['ngRoute']);
const context = (<any>require).context('../', true, /specs\.(tsx?|js)/);
const context = (require as any).context('../', true, /specs\.(tsx?|js)/);
for (const key of context.keys()) {
context(key);
}

View File

@ -18,5 +18,5 @@ jest.mock('app/features/plugins/plugin_loader', () => ({}));
configure({ adapter: new Adapter() });
const global = <any>window;
const global = window as any;
global.$ = global.jQuery = $;

View File

@ -1,10 +1,10 @@
declare var global: NodeJS.Global;
(<any>global).requestAnimationFrame = callback => {
(global as any).requestAnimationFrame = callback => {
setTimeout(callback, 0);
};
(<any>Promise.prototype).finally = function(onFinally) {
(Promise.prototype as any).finally = function(onFinally) {
return this.then(
/* onFulfilled */
res => Promise.resolve(onFinally()).then(() => res),

View File

@ -1,4 +1,4 @@
const _global = <any>window;
const _global = window as any;
const beforeEach = _global.beforeEach;
const afterEach = _global.afterEach;
const before = _global.before;

View File

@ -29,6 +29,7 @@
"label-position": true,
"max-line-length": [true, 150],
"member-access": [true, "no-public"],
"no-angle-bracket-type-assertion": true,
"no-arg": true,
"no-bitwise": false,
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
@ -37,6 +38,8 @@
"no-empty": false,
"no-eval": true,
"no-inferrable-types": true,
"no-namespace": [true, "allow-declarations"],
"no-reference": true,
"no-shadowed-variable": false,
"no-string-literal": false,
"no-switch-case-fall-through": false,
@ -56,7 +59,15 @@
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords"],
"variable-name": [
true,
"check-format",
"ban-keywords",
"allow-leading-underscore",
"allow-trailing-underscore",
"allow-pascal-case"
],
"use-isnan": true,
"whitespace": [true, "check-branch", "check-decl", "check-type", "check-preblock"]
}
}