|
@@ -14,6 +14,7 @@ import {MetricsPanelCtrl} from 'app/plugins/sdk';
|
|
|
class SingleStatCtrl extends MetricsPanelCtrl {
|
|
class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
static templateUrl = 'module.html';
|
|
static templateUrl = 'module.html';
|
|
|
|
|
|
|
|
|
|
+ dataType = 'timeseries';
|
|
|
series: any[];
|
|
series: any[];
|
|
|
data: any;
|
|
data: any;
|
|
|
fontSizes: any[];
|
|
fontSizes: any[];
|
|
@@ -22,6 +23,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
panel: any;
|
|
panel: any;
|
|
|
events: any;
|
|
events: any;
|
|
|
valueNameOptions: any[] = ['min','max','avg', 'current', 'total', 'name', 'first', 'delta', 'diff', 'range'];
|
|
valueNameOptions: any[] = ['min','max','avg', 'current', 'total', 'name', 'first', 'delta', 'diff', 'range'];
|
|
|
|
|
+ tableColumnOptions: any;
|
|
|
|
|
|
|
|
// Set and populate defaults
|
|
// Set and populate defaults
|
|
|
panelDefaults = {
|
|
panelDefaults = {
|
|
@@ -67,7 +69,8 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
maxValue: 100,
|
|
maxValue: 100,
|
|
|
thresholdMarkers: true,
|
|
thresholdMarkers: true,
|
|
|
thresholdLabels: false
|
|
thresholdLabels: false
|
|
|
- }
|
|
|
|
|
|
|
+ },
|
|
|
|
|
+ tableColumn: ''
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** @ngInject */
|
|
/** @ngInject */
|
|
@@ -98,11 +101,16 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
onDataReceived(dataList) {
|
|
onDataReceived(dataList) {
|
|
|
- this.series = dataList.map(this.seriesHandler.bind(this));
|
|
|
|
|
-
|
|
|
|
|
- var data: any = {};
|
|
|
|
|
- this.setValues(data);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ const data: any = {};
|
|
|
|
|
+ if (dataList.length > 0 && dataList[0].type === 'table'){
|
|
|
|
|
+ this.dataType = 'table';
|
|
|
|
|
+ const tableData = dataList.map(this.tableHandler.bind(this));
|
|
|
|
|
+ this.setTableValues(tableData, data);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.dataType = 'timeseries';
|
|
|
|
|
+ this.series = dataList.map(this.seriesHandler.bind(this));
|
|
|
|
|
+ this.setValues(data);
|
|
|
|
|
+ }
|
|
|
this.data = data;
|
|
this.data = data;
|
|
|
this.render();
|
|
this.render();
|
|
|
}
|
|
}
|
|
@@ -117,6 +125,69 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
return series;
|
|
return series;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ tableHandler(tableData) {
|
|
|
|
|
+ const datapoints = [];
|
|
|
|
|
+ const columnNames = {};
|
|
|
|
|
+
|
|
|
|
|
+ tableData.columns.forEach((column, columnIndex) => {
|
|
|
|
|
+ columnNames[columnIndex] = column.text;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.tableColumnOptions = columnNames;
|
|
|
|
|
+ if (!_.find(tableData.columns, ['text', this.panel.tableColumn])) {
|
|
|
|
|
+ this.setTableColumnToSensibleDefault(tableData);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tableData.rows.forEach((row) => {
|
|
|
|
|
+ const datapoint = {};
|
|
|
|
|
+
|
|
|
|
|
+ row.forEach((value, columnIndex) => {
|
|
|
|
|
+ const key = columnNames[columnIndex];
|
|
|
|
|
+ datapoint[key] = value;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ datapoints.push(datapoint);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return datapoints;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setTableColumnToSensibleDefault(tableData) {
|
|
|
|
|
+ if (this.tableColumnOptions.length === 1) {
|
|
|
|
|
+ this.panel.tableColumn = this.tableColumnOptions[0];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.panel.tableColumn = _.find(tableData.columns, (col) => { return col.type !== 'time'; }).text;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setTableValues(tableData, data) {
|
|
|
|
|
+ if (!tableData || tableData.length === 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (tableData[0].length === 0 || !tableData[0][0][this.panel.tableColumn]) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let highestValue = 0;
|
|
|
|
|
+ let lowestValue = Number.MAX_VALUE;
|
|
|
|
|
+ const datapoint = tableData[0][0];
|
|
|
|
|
+ data.value = datapoint[this.panel.tableColumn];
|
|
|
|
|
+
|
|
|
|
|
+ if (_.isString(data.value)) {
|
|
|
|
|
+ data.valueFormatted = _.escape(data.value);
|
|
|
|
|
+ data.value = 0;
|
|
|
|
|
+ data.valueRounded = 0;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const decimalInfo = this.getDecimalsForValue(data.value);
|
|
|
|
|
+ const formatFunc = kbn.valueFormats[this.panel.format];
|
|
|
|
|
+ data.valueFormatted = formatFunc(datapoint[this.panel.tableColumn], decimalInfo.decimals, decimalInfo.scaledDecimals);
|
|
|
|
|
+ data.valueRounded = kbn.roundValue(data.value, this.panel.decimals || 0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setValueMapping(data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
setColoring(options) {
|
|
setColoring(options) {
|
|
|
if (options.background) {
|
|
if (options.background) {
|
|
|
this.panel.colorValue = false;
|
|
this.panel.colorValue = false;
|
|
@@ -192,10 +263,10 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
if (this.panel.valueName === 'name') {
|
|
if (this.panel.valueName === 'name') {
|
|
|
data.value = 0;
|
|
data.value = 0;
|
|
|
data.valueRounded = 0;
|
|
data.valueRounded = 0;
|
|
|
- data.valueFormated = this.series[0].alias;
|
|
|
|
|
|
|
+ data.valueFormatted = this.series[0].alias;
|
|
|
} else if (_.isString(lastValue)) {
|
|
} else if (_.isString(lastValue)) {
|
|
|
data.value = 0;
|
|
data.value = 0;
|
|
|
- data.valueFormated = _.escape(lastValue);
|
|
|
|
|
|
|
+ data.valueFormatted = _.escape(lastValue);
|
|
|
data.valueRounded = 0;
|
|
data.valueRounded = 0;
|
|
|
} else {
|
|
} else {
|
|
|
data.value = this.series[0].stats[this.panel.valueName];
|
|
data.value = this.series[0].stats[this.panel.valueName];
|
|
@@ -203,7 +274,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
|
|
|
|
|
var decimalInfo = this.getDecimalsForValue(data.value);
|
|
var decimalInfo = this.getDecimalsForValue(data.value);
|
|
|
var formatFunc = kbn.valueFormats[this.panel.format];
|
|
var formatFunc = kbn.valueFormats[this.panel.format];
|
|
|
- data.valueFormated = formatFunc(data.value, decimalInfo.decimals, decimalInfo.scaledDecimals);
|
|
|
|
|
|
|
+ data.valueFormatted = formatFunc(data.value, decimalInfo.decimals, decimalInfo.scaledDecimals);
|
|
|
data.valueRounded = kbn.roundValue(data.value, decimalInfo.decimals);
|
|
data.valueRounded = kbn.roundValue(data.value, decimalInfo.decimals);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -211,7 +282,10 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
data.scopedVars = _.extend({}, this.panel.scopedVars);
|
|
data.scopedVars = _.extend({}, this.panel.scopedVars);
|
|
|
data.scopedVars["__name"] = {value: this.series[0].label};
|
|
data.scopedVars["__name"] = {value: this.series[0].label};
|
|
|
}
|
|
}
|
|
|
|
|
+ this.setValueMapping(data);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ setValueMapping(data) {
|
|
|
// check value to text mappings if its enabled
|
|
// check value to text mappings if its enabled
|
|
|
if (this.panel.mappingType === 1) {
|
|
if (this.panel.mappingType === 1) {
|
|
|
for (let i = 0; i < this.panel.valueMaps.length; i++) {
|
|
for (let i = 0; i < this.panel.valueMaps.length; i++) {
|
|
@@ -219,7 +293,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
// special null case
|
|
// special null case
|
|
|
if (map.value === 'null') {
|
|
if (map.value === 'null') {
|
|
|
if (data.value === null || data.value === void 0) {
|
|
if (data.value === null || data.value === void 0) {
|
|
|
- data.valueFormated = map.text;
|
|
|
|
|
|
|
+ data.valueFormatted = map.text;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
continue;
|
|
continue;
|
|
@@ -228,7 +302,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
// value/number to text mapping
|
|
// value/number to text mapping
|
|
|
var value = parseFloat(map.value);
|
|
var value = parseFloat(map.value);
|
|
|
if (value === data.valueRounded) {
|
|
if (value === data.valueRounded) {
|
|
|
- data.valueFormated = map.text;
|
|
|
|
|
|
|
+ data.valueFormatted = map.text;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -238,7 +312,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
// special null case
|
|
// special null case
|
|
|
if (map.from === 'null' && map.to === 'null') {
|
|
if (map.from === 'null' && map.to === 'null') {
|
|
|
if (data.value === null || data.value === void 0) {
|
|
if (data.value === null || data.value === void 0) {
|
|
|
- data.valueFormated = map.text;
|
|
|
|
|
|
|
+ data.valueFormatted = map.text;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
continue;
|
|
continue;
|
|
@@ -248,14 +322,14 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
var from = parseFloat(map.from);
|
|
var from = parseFloat(map.from);
|
|
|
var to = parseFloat(map.to);
|
|
var to = parseFloat(map.to);
|
|
|
if (to >= data.valueRounded && from <= data.valueRounded) {
|
|
if (to >= data.valueRounded && from <= data.valueRounded) {
|
|
|
- data.valueFormated = map.text;
|
|
|
|
|
|
|
+ data.valueFormatted = map.text;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (data.value === null || data.value === void 0) {
|
|
if (data.value === null || data.value === void 0) {
|
|
|
- data.valueFormated = "no value";
|
|
|
|
|
|
|
+ data.valueFormatted = "no value";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -317,7 +391,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
|
|
|
|
|
if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, panel.prefix); }
|
|
if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, panel.prefix); }
|
|
|
|
|
|
|
|
- var value = applyColoringThresholds(data.value, data.valueFormated);
|
|
|
|
|
|
|
+ var value = applyColoringThresholds(data.value, data.valueFormatted);
|
|
|
body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
|
|
body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
|
|
|
|
|
|
|
|
if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
|
|
if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
|
|
@@ -329,7 +403,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|
|
|
|
|
|
|
function getValueText() {
|
|
function getValueText() {
|
|
|
var result = panel.prefix ? panel.prefix : '';
|
|
var result = panel.prefix ? panel.prefix : '';
|
|
|
- result += data.valueFormated;
|
|
|
|
|
|
|
+ result += data.valueFormatted;
|
|
|
result += panel.postfix ? panel.postfix : '';
|
|
result += panel.postfix ? panel.postfix : '';
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|