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 ## User sessions
The second thing to consider is how to deal with user sessions and how to configure your load balancer infront of Grafana. 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 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). 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', '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; const moduleName = 'grafana.' + type;
this.useModule(angular.module(moduleName, [])); this.useModule(angular.module(moduleName, []));
}); });

View File

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

View File

@ -11,9 +11,9 @@ export class Settings {
datasources: any; datasources: any;
panels: any; panels: any;
appSubUrl: string; appSubUrl: string;
window_title_prefix: string; windowTitlePrefix: string;
buildInfo: BuildInfo; buildInfo: BuildInfo;
new_panel_title: string; newPanelTitle: string;
bootData: any; bootData: any;
externalUserMngLinkUrl: string; externalUserMngLinkUrl: string;
externalUserMngLinkName: 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; const options = bootData.settings;
options.bootData = bootData; options.bootData = bootData;

View File

@ -60,7 +60,7 @@ export class InspectCtrl {
if (keyValue[1].length > 0) { if (keyValue[1].length > 0) {
result.push({ result.push({
key: keyValue[0], 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.keys().forEach(function(key) {
templates(key); templates(key);
}); });

View File

@ -12,13 +12,13 @@ export class Analytics {
dataType: 'script', dataType: 'script',
cache: true, cache: true,
}); });
const ga = ((<any>window).ga = const ga = ((window as any).ga =
(<any>window).ga || (window as any).ga ||
function() { function() {
(ga.q = ga.q || []).push(arguments); (ga.q = ga.q || []).push(arguments);
}); });
ga.l = +new Date(); ga.l = +new Date();
ga('create', (<any>config).googleAnalyticsId, 'auto'); ga('create', (config as any).googleAnalyticsId, 'auto');
ga('set', 'anonymizeIp', true); ga('set', 'anonymizeIp', true);
return ga; return ga;
} }
@ -26,7 +26,7 @@ export class Analytics {
init() { init() {
this.$rootScope.$on('$viewContentLoaded', () => { this.$rootScope.$on('$viewContentLoaded', () => {
const track = { page: this.$location.url() }; 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('set', track);
ga('send', 'pageview'); ga('send', 'pageview');
}); });
@ -35,7 +35,7 @@ export class Analytics {
/** @ngInject */ /** @ngInject */
function startAnalytics(googleAnalyticsSrv) { function startAnalytics(googleAnalyticsSrv) {
if ((<any>config).googleAnalyticsId) { if ((config as any).googleAnalyticsId) {
googleAnalyticsSrv.init(); 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) => {}, search: (options: any) => {},
getDashboardTags: () => {}, getDashboardTags: () => {},
}; };
const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, <SearchSrv>searchSrvStub); const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, searchSrvStub as SearchSrv);
describe('Given an empty result', () => { describe('Given an empty result', () => {
beforeEach(() => { beforeEach(() => {

View File

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

View File

@ -26,8 +26,8 @@ export function tickStep(start: number, stop: number, count: number): number {
return stop < start ? -step1 : step1; return stop < start ? -step1 : step1;
} }
export function getScaledDecimals(decimals, tick_size) { export function getScaledDecimals(decimals, tickSize) {
return decimals - Math.floor(Math.log(tick_size) / Math.LN10); 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) * Get decimal precision of number stored as a string ("3.14" => 2)
*/ */
export function getStringPrecision(num: string): number { export function getStringPrecision(num: string): number {
const dot_index = num.indexOf('.'); const dotIndex = num.indexOf('.');
if (dot_index === -1) { if (dotIndex === -1) {
return 0; return 0;
} else { } 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 { export function isVersionGtOrEq(a: string, b: string): boolean {
const a_semver = new SemVersion(a); const aSemver = new SemVersion(a);
return a_semver.isGtOrEq(b); return aSemver.isGtOrEq(b);
} }

View File

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

View File

@ -106,7 +106,7 @@ export class DashboardLoaderSrv {
}; };
/*jshint -W054 */ /*jshint -W054 */
const script_func = new Function( const scriptFunc = new Function(
'ARGS', 'ARGS',
'kbn', 'kbn',
'dateMath', 'dateMath',
@ -119,12 +119,12 @@ export class DashboardLoaderSrv {
'services', 'services',
result.data 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 // Handle async dashboard scripts
if (_.isFunction(script_result)) { if (_.isFunction(scriptResult)) {
const deferred = this.$q.defer(); const deferred = this.$q.defer();
script_result(dashboard => { scriptResult(dashboard => {
this.$timeout(() => { this.$timeout(() => {
deferred.resolve({ data: dashboard }); deferred.resolve({ data: dashboard });
}); });
@ -132,7 +132,7 @@ export class DashboardLoaderSrv {
return deferred.promise; 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')); const utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z'));
// Older browser does not the internationalization API // Older browser does not the internationalization API
if (!(<any>window).Intl) { if (!(window as any).Intl) {
return utcOffset; return utcOffset;
} }
const dateFormat = (<any>window).Intl.DateTimeFormat(); const dateFormat = (window as any).Intl.DateTimeFormat();
if (!dateFormat.resolvedOptions) { if (!dateFormat.resolvedOptions) {
return utcOffset; 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', () => { it('should panels in self row', () => {
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual([ expect(panelTypes).toEqual([
'row', 'row',
'graph', 'graph',
'graph', 'graph',
@ -350,8 +350,8 @@ describe('given dashboard with row repeat', function() {
}); });
it('should not repeat only row', function() { it('should not repeat only row', function() {
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']); expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']);
}); });
it('should set scopedVars for each panel', function() { it('should set scopedVars for each panel', function() {
@ -399,8 +399,8 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON); dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats(); dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'row', 'row', 'graph']); expect(panelTypes).toEqual(['row', 'row', 'row', 'graph']);
expect(dashboard.panels[0].panels).toHaveLength(2); expect(dashboard.panels[0].panels).toHaveLength(2);
expect(dashboard.panels[1].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 = new DashboardModel(dashboardJSON);
dashboard.processRepeats(); dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual([ expect(panelTypes).toEqual([
'row', 'row',
'graph', 'graph',
'graph', 'graph',
@ -488,7 +488,7 @@ describe('given dashboard with row repeat', function() {
dashboard = new DashboardModel(dashboardJSON); dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats(); dashboard.processRepeats();
const panel_ids = _.flattenDeep( const panelIds = _.flattenDeep(
_.map(dashboard.panels, panel => { _.map(dashboard.panels, panel => {
let ids = []; let ids = [];
if (panel.panels && panel.panels.length) { if (panel.panels && panel.panels.length) {
@ -498,7 +498,7 @@ describe('given dashboard with row repeat', function() {
return ids; 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() { 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 = new DashboardModel(dashboardJSON);
dashboard.processRepeats(); dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']); expect(panelTypes).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']);
const panel_y_positions = _.map(dashboard.panels, p => p.gridPos.y); const panelYPositions = _.map(dashboard.panels, p => p.gridPos.y);
expect(panel_y_positions).toEqual([0, 1, 1, 5, 7, 8, 8, 12]); 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', () => { it('should repeat row and panels for each row', () => {
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']); expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
}); });
it('should clean up old repeated panels', () => { it('should clean up old repeated panels', () => {
@ -592,8 +592,8 @@ describe('given dashboard with row and panel repeat', () => {
dashboard = new DashboardModel(dashboardJSON); dashboard = new DashboardModel(dashboardJSON);
dashboard.processRepeats(); dashboard.processRepeats();
const panel_types = _.map(dashboard.panels, 'type'); const panelTypes = _.map(dashboard.panels, 'type');
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']); expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
}); });
it('should set scopedVars for each row', () => { 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'; import { LinkSrv } from 'app/features/panellinks/link_srv';
describe('ShareModalCtrl', () => { describe('ShareModalCtrl', () => {
const ctx = <any>{ const ctx = {
timeSrv: { timeSrv: {
timeRange: () => { timeRange: () => {
return { from: new Date(1000), to: new Date(2000) }; return { from: new Date(1000), to: new Date(2000) };
@ -26,9 +26,9 @@ describe('ShareModalCtrl', () => {
templateSrv: { templateSrv: {
fillVariableValuesForUrl: () => {}, fillVariableValuesForUrl: () => {},
}, },
}; } as any;
(<any>window).Intl.DateTimeFormat = () => { (window as any).Intl.DateTimeFormat = () => {
return { return {
resolvedOptions: () => { resolvedOptions: () => {
return { timeZone: 'UTC' }; return { timeZone: 'UTC' };

View File

@ -3,7 +3,7 @@ import { coreModule } from 'app/core/core';
export class ProfileCtrl { export class ProfileCtrl {
user: any; user: any;
old_theme: any; oldTheme: any;
teams: any = []; teams: any = [];
orgs: any = []; orgs: any = [];
userForm: any; userForm: any;
@ -54,7 +54,7 @@ export class ProfileCtrl {
this.backendSrv.put('/api/user/', this.user).then(() => { this.backendSrv.put('/api/user/', this.user).then(() => {
this.contextSrv.user.name = this.user.name || this.user.login; 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(); 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 { export class IntervalVariable implements Variable {
name: string; name: string;
auto_count: number; auto_count: number; // tslint:disable-line variable-name
auto_min: number; auto_min: number; // tslint:disable-line variable-name
options: any; options: any;
auto: boolean; auto: boolean;
query: string; query: string;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,27 +12,27 @@ export default class PrometheusMetricFindQuery {
} }
process() { process() {
const label_values_regex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)\s*$/; const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)\s*$/;
const metric_names_regex = /^metrics\((.+)\)\s*$/; const metricNamesRegex = /^metrics\((.+)\)\s*$/;
const query_result_regex = /^query_result\((.+)\)\s*$/; const queryResultRegex = /^query_result\((.+)\)\s*$/;
const label_values_query = this.query.match(label_values_regex); const labelValuesQuery = this.query.match(labelValuesRegex);
if (label_values_query) { if (labelValuesQuery) {
if (label_values_query[1]) { if (labelValuesQuery[1]) {
return this.labelValuesQuery(label_values_query[2], label_values_query[1]); return this.labelValuesQuery(labelValuesQuery[2], labelValuesQuery[1]);
} else { } 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); const metricNamesQuery = this.query.match(metricNamesRegex);
if (metric_names_query) { if (metricNamesQuery) {
return this.metricNameQuery(metric_names_query[1]); return this.metricNameQuery(metricNamesQuery[1]);
} }
const query_result_query = this.query.match(query_result_regex); const queryResultQuery = this.query.match(queryResultRegex);
if (query_result_query) { if (queryResultQuery) {
return this.queryResultQuery(query_result_query[1]); return this.queryResultQuery(queryResultQuery[1]);
} }
// if query contains full metric name, return metric name and label list // 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) { for (const value of metricData.values) {
let dp_value = parseFloat(value[1]); let dpValue = parseFloat(value[1]);
if (_.isNaN(dp_value)) { if (_.isNaN(dpValue)) {
dp_value = null; dpValue = null;
} }
const timestamp = parseFloat(value[0]) * 1000; const timestamp = parseFloat(value[0]) * 1000;
@ -55,7 +55,7 @@ export class ResultTransformer {
dps.push([null, t]); dps.push([null, t]);
} }
baseTimestamp = timestamp + stepMs; baseTimestamp = timestamp + stepMs;
dps.push([dp_value, timestamp]); dps.push([dpValue, timestamp]);
} }
const endTimestamp = end * 1000; const endTimestamp = end * 1000;

View File

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

View File

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

View File

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

View File

@ -47,12 +47,12 @@ export function convertValuesToHistogram(values: number[], bucketSize: number, m
histogram[bound] = histogram[bound] + 1; histogram[bound] = histogram[bound] + 1;
} }
const histogam_series = _.map(histogram, (count, bound) => { const histogamSeries = _.map(histogram, (count, bound) => {
return [Number(bound), count]; return [Number(bound), count];
}); });
// Sort by Y axis values // 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 $ from 'jquery';
import { graphDirective } from '../graph'; import { graphDirective } from '../graph';
const ctx = <any>{}; const ctx = {} as any;
let ctrl; let ctrl;
const scope = { const scope = {
ctrl: {}, ctrl: {},
@ -47,7 +47,7 @@ describe('grafanaGraph', function() {
lightTheme: false, lightTheme: false,
}, },
}; };
GraphCtrl.prototype = <any>{ GraphCtrl.prototype = {
...MetricsPanelCtrl.prototype, ...MetricsPanelCtrl.prototype,
...PanelCtrl.prototype, ...PanelCtrl.prototype,
...GraphCtrl.prototype, ...GraphCtrl.prototype,
@ -88,7 +88,7 @@ describe('grafanaGraph', function() {
from: moment([2015, 1, 1, 10]), from: moment([2015, 1, 1, 10]),
to: moment([2015, 1, 1, 22]), to: moment([2015, 1, 1, 22]),
}, },
}; } as any;
ctx.data = []; ctx.data = [];
ctx.data.push( ctx.data.push(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ angular.module('grafana.directives', []);
angular.module('grafana.filters', []); angular.module('grafana.filters', []);
angular.module('grafana.routes', ['ngRoute']); 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()) { for (const key of context.keys()) {
context(key); context(key);
} }

View File

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

View File

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

View File

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