diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts
index c8384b5b40a..ef2e6b9c8b2 100644
--- a/public/app/core/time_series2.ts
+++ b/public/app/core/time_series2.ts
@@ -41,6 +41,7 @@ export default class TimeSeries {
nullPointMode: any;
fillBelowTo: any;
transform: any;
+ flotpairs: any;
constructor(opts) {
this.datapoints = opts.datapoints;
diff --git a/public/app/plugins/panel/singlestat/controller.js b/public/app/plugins/panel/singlestat/controller.ts
similarity index 92%
rename from public/app/plugins/panel/singlestat/controller.js
rename to public/app/plugins/panel/singlestat/controller.ts
index 62ae13d0f5f..4b55a4568be 100644
--- a/public/app/plugins/panel/singlestat/controller.js
+++ b/public/app/plugins/panel/singlestat/controller.ts
@@ -1,17 +1,15 @@
-define([
- 'angular',
- 'app/app',
- 'lodash',
- 'app/core/utils/kbn',
- 'app/core/time_series',
- 'app/features/panel/panel_meta',
-],
-function (angular, app, _, kbn, TimeSeries, PanelMeta) {
- 'use strict';
+///
+
+import angular from 'angular';
+import _ from 'lodash';
+import kbn from 'app/core/utils/kbn';
+import PanelMeta from 'app/features/panel/panel_meta2';
+import TimeSeries from '../../../core/time_series2';
+
+export class SingleStatCtrl {
/** @ngInject */
- function SingleStatCtrl($scope, panelSrv, panelHelper) {
-
+ constructor($scope, panelSrv, panelHelper) {
$scope.panelMeta = new PanelMeta({
panelName: 'Singlestat',
editIcon: "fa fa-dashboard",
@@ -57,6 +55,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
};
_.defaults($scope.panel, _d);
+
$scope.unitFormats = kbn.getUnitFormats();
$scope.setUnitFormat = function(subItem) {
@@ -104,8 +103,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
if (options.background) {
$scope.panel.colorValue = false;
$scope.panel.colors = ['rgba(71, 212, 59, 0.4)', 'rgba(245, 150, 40, 0.73)', 'rgba(225, 40, 40, 0.59)'];
- }
- else {
+ } else {
$scope.panel.colorBackground = false;
$scope.panel.colors = ['rgba(50, 172, 45, 0.97)', 'rgba(237, 129, 40, 0.89)', 'rgba(245, 54, 54, 0.9)'];
}
@@ -151,7 +149,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
// reduce starting decimals if not needed
if (Math.floor(value) === value) { dec = 0; }
- var result = {};
+ var result: any = {};
result.decimals = Math.max(0, dec);
result.scaledDecimals = result.decimals - Math.floor(Math.log(size) / Math.LN10) + 2;
@@ -159,7 +157,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
};
$scope.render = function() {
- var data = {};
+ var data: any = {};
$scope.setValues(data);
@@ -176,7 +174,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
$scope.setValues = function(data) {
data.flotpairs = [];
- if($scope.series.length > 1) {
+ if ($scope.series.length > 1) {
$scope.inspector.error = new Error();
$scope.inspector.error.message = 'Multiple Series Error';
$scope.inspector.error.data = 'Metric query returns ' + $scope.series.length +
@@ -204,7 +202,7 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
}
// check value to text mappings
- for(var i = 0; i < $scope.panel.valueMaps.length; i++) {
+ for (var i = 0; i < $scope.panel.valueMaps.length; i++) {
var map = $scope.panel.valueMaps[i];
// special null case
if (map.value === 'null') {
@@ -239,7 +237,6 @@ function (angular, app, _, kbn, TimeSeries, PanelMeta) {
};
$scope.init();
- }
- return SingleStatCtrl;
-});
+ }
+}
diff --git a/public/app/plugins/panel/singlestat/module.js b/public/app/plugins/panel/singlestat/module.js
deleted file mode 100644
index 8ce441818e6..00000000000
--- a/public/app/plugins/panel/singlestat/module.js
+++ /dev/null
@@ -1,235 +0,0 @@
-define([
- './controller',
- 'lodash',
- 'jquery',
- 'jquery.flot',
-],
-function (SingleStatCtrl, _, $) {
- 'use strict';
-
- /** @ngInject */
- function singleStatPanel($location, linkSrv, $timeout, templateSrv) {
- return {
- controller: SingleStatCtrl,
- templateUrl: 'app/plugins/panel/singlestat/module.html',
- link: function(scope, elem) {
- var data, panel, linkInfo, $panelContainer;
- var firstRender = true;
-
- scope.$on('render', function() {
- if (firstRender) {
- var inner = elem.find('.singlestat-panel');
- if (inner.length) {
- elem = inner;
- $panelContainer = elem.parents('.panel-container');
- firstRender = false;
- hookupDrilldownLinkTooltip();
- }
- }
-
- render();
- scope.panelRenderingComplete();
- });
-
- function setElementHeight() {
- try {
- var height = scope.height || panel.height || scope.row.height;
- if (_.isString(height)) {
- height = parseInt(height.replace('px', ''), 10);
- }
-
- height -= 5; // padding
- height -= panel.title ? 24 : 9; // subtract panel title bar
-
- elem.css('height', height + 'px');
-
- return true;
- } catch(e) { // IE throws errors sometimes
- return false;
- }
- }
-
- function applyColoringThresholds(value, valueString) {
- if (!panel.colorValue) {
- return valueString;
- }
-
- var color = getColorForValue(value);
- if (color) {
- return ''+ valueString + '';
- }
-
- return valueString;
- }
-
- function getColorForValue(value) {
- for (var i = data.thresholds.length - 1; i >= 0 ; i--) {
- if (value >= data.thresholds[i]) {
- return data.colorMap[i];
- }
- }
- return null;
- }
-
- function getSpan(className, fontSize, value) {
- value = templateSrv.replace(value);
- return '' +
- value + '';
- }
-
- function getBigValueHtml() {
- var body = '
';
-
- if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, scope.panel.prefix); }
-
- var value = applyColoringThresholds(data.valueRounded, data.valueFormated);
- body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
-
- if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
-
- body += '
';
-
- return body;
- }
-
- function addSparkline() {
- var panel = scope.panel;
- var width = elem.width() + 20;
- var height = elem.height() || 100;
-
- var plotCanvas = $('');
- var plotCss = {};
- plotCss.position = 'absolute';
-
- if (panel.sparkline.full) {
- plotCss.bottom = '5px';
- plotCss.left = '-5px';
- plotCss.width = (width - 10) + 'px';
- var dynamicHeightMargin = height <= 100 ? 5 : (Math.round((height/100)) * 15) + 5;
- plotCss.height = (height - dynamicHeightMargin) + 'px';
- }
- else {
- plotCss.bottom = "0px";
- plotCss.left = "-5px";
- plotCss.width = (width - 10) + 'px';
- plotCss.height = Math.floor(height * 0.25) + "px";
- }
-
- plotCanvas.css(plotCss);
-
- var options = {
- legend: { show: false },
- series: {
- lines: {
- show: true,
- fill: 1,
- lineWidth: 1,
- fillColor: panel.sparkline.fillColor,
- },
- },
- yaxes: { show: false },
- xaxis: {
- show: false,
- mode: "time",
- min: scope.range.from.valueOf(),
- max: scope.range.to.valueOf(),
- },
- grid: { hoverable: false, show: false },
- };
-
- elem.append(plotCanvas);
-
- var plotSeries = {
- data: data.flotpairs,
- color: panel.sparkline.lineColor
- };
-
- $.plot(plotCanvas, [plotSeries], options);
- }
-
- function render() {
- if (!scope.data) { return; }
-
- data = scope.data;
- panel = scope.panel;
-
- setElementHeight();
-
- var body = getBigValueHtml();
-
- if (panel.colorBackground && !isNaN(data.valueRounded)) {
- var color = getColorForValue(data.valueRounded);
- if (color) {
- $panelContainer.css('background-color', color);
- if (scope.fullscreen) {
- elem.css('background-color', color);
- } else {
- elem.css('background-color', '');
- }
- }
- } else {
- $panelContainer.css('background-color', '');
- elem.css('background-color', '');
- }
-
- elem.html(body);
-
- if (panel.sparkline.show) {
- addSparkline();
- }
-
- elem.toggleClass('pointer', panel.links.length > 0);
-
- if (panel.links.length > 0) {
- linkInfo = linkSrv.getPanelLinkAnchorInfo(panel.links[0], scope.panel.scopedVars);
- } else {
- linkInfo = null;
- }
- }
-
- function hookupDrilldownLinkTooltip() {
- // drilldown link tooltip
- var drilldownTooltip = $('hello
"');
-
- elem.mouseleave(function() {
- if (panel.links.length === 0) { return;}
- drilldownTooltip.detach();
- });
-
- elem.click(function(evt) {
- if (!linkInfo) { return; }
- // ignore title clicks in title
- if ($(evt).parents('.panel-header').length > 0) { return; }
-
- if (linkInfo.target === '_blank') {
- var redirectWindow = window.open(linkInfo.href, '_blank');
- redirectWindow.location;
- return;
- }
-
- if (linkInfo.href.indexOf('http') === 0) {
- window.location.href = linkInfo.href;
- } else {
- $timeout(function() {
- $location.url(linkInfo.href);
- });
- }
-
- drilldownTooltip.detach();
- });
-
- elem.mousemove(function(e) {
- if (!linkInfo) { return;}
-
- drilldownTooltip.text('click to go to: ' + linkInfo.title);
- drilldownTooltip.place_tt(e.pageX+20, e.pageY-15);
- });
- }
- }
- };
- }
-
- return {
- panel: singleStatPanel
- };
-});
diff --git a/public/app/plugins/panel/singlestat/module.ts b/public/app/plugins/panel/singlestat/module.ts
new file mode 100644
index 00000000000..c6d10afb567
--- /dev/null
+++ b/public/app/plugins/panel/singlestat/module.ts
@@ -0,0 +1,231 @@
+///
+
+import _ from 'lodash';
+import $ from 'jquery';
+import angular from 'angular';
+import {SingleStatCtrl} from './controller';
+
+angular.module('grafana.directives').directive('singleStatPanel', singleStatPanel);
+
+function singleStatPanel($location, linkSrv, $timeout, templateSrv) {
+ 'use strict';
+ return {
+ controller: SingleStatCtrl,
+ templateUrl: 'app/plugins/panel/singlestat/module.html',
+ link: function(scope, elem) {
+ var data, panel, linkInfo, $panelContainer;
+ var firstRender = true;
+
+ scope.$on('render', function() {
+ if (firstRender) {
+ var inner = elem.find('.singlestat-panel');
+ if (inner.length) {
+ elem = inner;
+ $panelContainer = elem.parents('.panel-container');
+ firstRender = false;
+ hookupDrilldownLinkTooltip();
+ }
+ }
+
+ render();
+ scope.panelRenderingComplete();
+ });
+
+ function setElementHeight() {
+ try {
+ var height = scope.height || panel.height || scope.row.height;
+ if (_.isString(height)) {
+ height = parseInt(height.replace('px', ''), 10);
+ }
+
+ height -= 5; // padding
+ height -= panel.title ? 24 : 9; // subtract panel title bar
+
+ elem.css('height', height + 'px');
+
+ return true;
+ } catch (e) { // IE throws errors sometimes
+ return false;
+ }
+ }
+
+ function applyColoringThresholds(value, valueString) {
+ if (!panel.colorValue) {
+ return valueString;
+ }
+
+ var color = getColorForValue(value);
+ if (color) {
+ return ''+ valueString + '';
+ }
+
+ return valueString;
+ }
+
+ function getColorForValue(value) {
+ for (var i = data.thresholds.length - 1; i >= 0 ; i--) {
+ if (value >= data.thresholds[i]) {
+ return data.colorMap[i];
+ }
+ }
+ return null;
+ }
+
+ function getSpan(className, fontSize, value) {
+ value = templateSrv.replace(value);
+ return '' +
+ value + '';
+ }
+
+ function getBigValueHtml() {
+ var body = '';
+
+ if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, scope.panel.prefix); }
+
+ var value = applyColoringThresholds(data.valueRounded, data.valueFormated);
+ body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
+
+ if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
+
+ body += '
';
+
+ return body;
+ }
+
+ function addSparkline() {
+ var panel = scope.panel;
+ var width = elem.width() + 20;
+ var height = elem.height() || 100;
+
+ var plotCanvas = $('');
+ var plotCss: any = {};
+ plotCss.position = 'absolute';
+
+ if (panel.sparkline.full) {
+ plotCss.bottom = '5px';
+ plotCss.left = '-5px';
+ plotCss.width = (width - 10) + 'px';
+ var dynamicHeightMargin = height <= 100 ? 5 : (Math.round((height/100)) * 15) + 5;
+ plotCss.height = (height - dynamicHeightMargin) + 'px';
+ } else {
+ plotCss.bottom = "0px";
+ plotCss.left = "-5px";
+ plotCss.width = (width - 10) + 'px';
+ plotCss.height = Math.floor(height * 0.25) + "px";
+ }
+
+ plotCanvas.css(plotCss);
+
+ var options = {
+ legend: { show: false },
+ series: {
+ lines: {
+ show: true,
+ fill: 1,
+ lineWidth: 1,
+ fillColor: panel.sparkline.fillColor,
+ },
+ },
+ yaxes: { show: false },
+ xaxis: {
+ show: false,
+ mode: "time",
+ min: scope.range.from.valueOf(),
+ max: scope.range.to.valueOf(),
+ },
+ grid: { hoverable: false, show: false },
+ };
+
+ elem.append(plotCanvas);
+
+ var plotSeries = {
+ data: data.flotpairs,
+ color: panel.sparkline.lineColor
+ };
+
+ $.plot(plotCanvas, [plotSeries], options);
+ }
+
+ function render() {
+ if (!scope.data) { return; }
+
+ data = scope.data;
+ panel = scope.panel;
+
+ setElementHeight();
+
+ var body = getBigValueHtml();
+
+ if (panel.colorBackground && !isNaN(data.valueRounded)) {
+ var color = getColorForValue(data.valueRounded);
+ if (color) {
+ $panelContainer.css('background-color', color);
+ if (scope.fullscreen) {
+ elem.css('background-color', color);
+ } else {
+ elem.css('background-color', '');
+ }
+ }
+ } else {
+ $panelContainer.css('background-color', '');
+ elem.css('background-color', '');
+ }
+
+ elem.html(body);
+
+ if (panel.sparkline.show) {
+ addSparkline();
+ }
+
+ elem.toggleClass('pointer', panel.links.length > 0);
+
+ if (panel.links.length > 0) {
+ linkInfo = linkSrv.getPanelLinkAnchorInfo(panel.links[0], scope.panel.scopedVars);
+ } else {
+ linkInfo = null;
+ }
+ }
+
+ function hookupDrilldownLinkTooltip() {
+ // drilldown link tooltip
+ var drilldownTooltip = $('hello
"');
+
+ elem.mouseleave(function() {
+ if (panel.links.length === 0) { return;}
+ drilldownTooltip.detach();
+ });
+
+ elem.click(function(evt) {
+ if (!linkInfo) { return; }
+ // ignore title clicks in title
+ if ($(evt).parents('.panel-header').length > 0) { return; }
+
+ if (linkInfo.target === '_blank') {
+ var redirectWindow = window.open(linkInfo.href, '_blank');
+ redirectWindow.location;
+ return;
+ }
+
+ if (linkInfo.href.indexOf('http') === 0) {
+ window.location.href = linkInfo.href;
+ } else {
+ $timeout(function() {
+ $location.url(linkInfo.href);
+ });
+ }
+
+ drilldownTooltip.detach();
+ });
+
+ elem.mousemove(function(e) {
+ if (!linkInfo) { return;}
+
+ drilldownTooltip.text('click to go to: ' + linkInfo.title);
+ drilldownTooltip.place_tt(e.pageX+20, e.pageY-15);
+ });
+ }
+ }
+ };
+}
+
+export {singleStatPanel as panel};
diff --git a/public/app/plugins/panel/singlestat/singleStatPanel.js b/public/app/plugins/panel/singlestat/singleStatPanel.js
deleted file mode 100644
index a176ea974ae..00000000000
--- a/public/app/plugins/panel/singlestat/singleStatPanel.js
+++ /dev/null
@@ -1,221 +0,0 @@
-define([
- 'angular',
- 'app/app',
- 'lodash',
- 'jquery',
- 'jquery.flot',
-],
-function (angular, app, _, $) {
- 'use strict';
-
- var module = angular.module('grafana.panels.singlestat', []);
- app.useModule(module);
-
- module.directive('singlestatPanel', function($location, linkSrv, $timeout, templateSrv) {
-
- return {
- link: function(scope, elem) {
- var data, panel, linkInfo;
- var $panelContainer = elem.parents('.panel-container');
-
- scope.$on('render', function() {
- render();
- scope.panelRenderingComplete();
- });
-
- function setElementHeight() {
- try {
- var height = scope.height || panel.height || scope.row.height;
- if (_.isString(height)) {
- height = parseInt(height.replace('px', ''), 10);
- }
-
- height -= 5; // padding
- height -= panel.title ? 24 : 9; // subtract panel title bar
-
- elem.css('height', height + 'px');
-
- return true;
- } catch(e) { // IE throws errors sometimes
- return false;
- }
- }
-
- function applyColoringThresholds(value, valueString) {
- if (!panel.colorValue) {
- return valueString;
- }
-
- var color = getColorForValue(value);
- if (color) {
- return ''+ valueString + '';
- }
-
- return valueString;
- }
-
- function getColorForValue(value) {
- for (var i = data.thresholds.length - 1; i >= 0 ; i--) {
- if (value >= data.thresholds[i]) {
- return data.colorMap[i];
- }
- }
- return null;
- }
-
- function getSpan(className, fontSize, value) {
- value = templateSrv.replace(value);
- return '' +
- value + '';
- }
-
- function getBigValueHtml() {
- var body = '';
-
- if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, scope.panel.prefix); }
-
- var value = applyColoringThresholds(data.valueRounded, data.valueFormated);
- body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
-
- if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
-
- body += '
';
-
- return body;
- }
-
- function addSparkline() {
- var panel = scope.panel;
- var width = elem.width() + 20;
- var height = elem.height() || 100;
-
- var plotCanvas = $('');
- var plotCss = {};
- plotCss.position = 'absolute';
-
- if (panel.sparkline.full) {
- plotCss.bottom = '5px';
- plotCss.left = '-5px';
- plotCss.width = (width - 10) + 'px';
- var dynamicHeightMargin = height <= 100 ? 5 : (Math.round((height/100)) * 15) + 5;
- plotCss.height = (height - dynamicHeightMargin) + 'px';
- }
- else {
- plotCss.bottom = "0px";
- plotCss.left = "-5px";
- plotCss.width = (width - 10) + 'px';
- plotCss.height = Math.floor(height * 0.25) + "px";
- }
-
- plotCanvas.css(plotCss);
-
- var options = {
- legend: { show: false },
- series: {
- lines: {
- show: true,
- fill: 1,
- lineWidth: 1,
- fillColor: panel.sparkline.fillColor,
- },
- },
- yaxes: { show: false },
- xaxis: {
- show: false,
- mode: "time",
- min: scope.range.from.valueOf(),
- max: scope.range.to.valueOf(),
- },
- grid: { hoverable: false, show: false },
- };
-
- elem.append(plotCanvas);
-
- var plotSeries = {
- data: data.flotpairs,
- color: panel.sparkline.lineColor
- };
-
- $.plot(plotCanvas, [plotSeries], options);
- }
-
- function render() {
- if (!scope.data) { return; }
-
- data = scope.data;
- panel = scope.panel;
-
- setElementHeight();
-
- var body = getBigValueHtml();
-
- if (panel.colorBackground && !isNaN(data.valueRounded)) {
- var color = getColorForValue(data.valueRounded);
- if (color) {
- $panelContainer.css('background-color', color);
- if (scope.fullscreen) {
- elem.css('background-color', color);
- } else {
- elem.css('background-color', '');
- }
- }
- } else {
- $panelContainer.css('background-color', '');
- elem.css('background-color', '');
- }
-
- elem.html(body);
-
- if (panel.sparkline.show) {
- addSparkline();
- }
-
- elem.toggleClass('pointer', panel.links.length > 0);
-
- if (panel.links.length > 0) {
- linkInfo = linkSrv.getPanelLinkAnchorInfo(panel.links[0], scope.panel.scopedVars);
- } else {
- linkInfo = null;
- }
- }
-
- // drilldown link tooltip
- var drilldownTooltip = $('hello
"');
-
- elem.mouseleave(function() {
- if (panel.links.length === 0) { return;}
- drilldownTooltip.detach();
- });
-
- elem.click(function() {
- if (!linkInfo) { return; }
-
- if (linkInfo.target === '_blank') {
- var redirectWindow = window.open(linkInfo.href, '_blank');
- redirectWindow.location;
- return;
- }
-
- if (linkInfo.href.indexOf('http') === 0) {
- window.location.href = linkInfo.href;
- } else {
- $timeout(function() {
- $location.url(linkInfo.href);
- });
- }
-
- drilldownTooltip.detach();
- });
-
- elem.mousemove(function(e) {
- if (!linkInfo) { return;}
-
- drilldownTooltip.text('click to go to: ' + linkInfo.title);
-
- drilldownTooltip.place_tt(e.pageX+20, e.pageY-15);
- });
- }
- };
- });
-
-});
diff --git a/public/app/plugins/panel/singlestat/specs/singlestat_panel_spec.ts b/public/app/plugins/panel/singlestat/specs/singlestat_panel_spec.ts
new file mode 100644
index 00000000000..e69de29bb2d