Merge pull request #153 from datadope-io/feature/ylabel_extratooltip

Added custom YLabel and Custom content on tooltip
This commit is contained in:
Ivan Mikheykin
2020-12-08 18:02:54 +03:00
committed by GitHub
13 changed files with 309 additions and 18 deletions
+38 -4
View File
@@ -245,12 +245,19 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
show: true,
freezeOnClick: true,
showItems: false,
items: [] // see tooltip_editor.ts
items: [],
// see tooltip_editor.ts
showExtraInfo: false,
extraInfo: ""
},
legend: {
show: true
},
yLabel: {
usingSplitLabel: false,
delimiter: "",
labelTemplate: ""
},
// how null points should be handled
nullPointMode: 'as empty',
yAxisSort: 'metrics',
@@ -665,14 +672,39 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
return bucketMatrix;
}
var targetIndex = {}; // Group indicies of elements in data by target (y label).
var targetIndex = {};
var targetPartials = {}; // Group indicies of elements in data by target (y label).
// lodash version:
//_.map(data, (d, i) => {
// targetIndex[d.target] = _.concat(_.toArray(targetIndex[d.target]), i);
//});
data.map(function (queryResult, i) {
var yLabel = queryResult.target;
// Init yLabel as the query target
var yLabel = queryResult.target; // Check if there is some labelTemplate configured
if (_this4.panel.yLabel.usingSplitLabel && _this4.panel.yLabel.delimiter != "") {
var pLabels = queryResult.target.split(_this4.panel.yLabel.delimiter); // Load all possible values as scoped vars and load them into targetPartials
// to be used on different components as Bucket and BucketMatrix props
var scopedVars = [];
scopedVars["__y_label"] = {
value: yLabel
};
for (var _i in pLabels) {
scopedVars["__y_label_".concat(_i)] = {
value: pLabels[_i]
};
}
if (_this4.panel.yLabel.labelTemplate != "") {
yLabel = _this4.templateSrv.replace(_this4.panel.yLabel.labelTemplate, scopedVars);
}
targetPartials[yLabel] = pLabels;
} //reset if it already exists
if (!targetIndex.hasOwnProperty(yLabel)) {
targetIndex[yLabel] = [];
@@ -757,6 +789,7 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
while (bucketFrom >= 0) {
var b = new Bucket();
b.yLabel = target;
b.pLabels = targetPartials[target];
b.relTo = lastTs - idx * intervalMs;
b.relFrom = lastTs - (idx + 1) * intervalMs;
b.to = b.relTo + from;
@@ -818,6 +851,7 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
}); //console.log ("bucketMatrix with values: ", bucketMatrix);
bucketMatrix.targets = targetKeys;
bucketMatrix.pLabels = targetPartials;
return bucketMatrix;
}
}]);
+1 -1
View File
File diff suppressed because one or more lines are too long
+54
View File
@@ -215,6 +215,60 @@
</div>
<div class="section gf-form-group">
<h5 class="section-heading">Y-axis label</h5>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Split query alias" label-class="width-12"
checked="ctrl.panel.yLabel.usingSplitLabel" on-change="ctrl.refresh()"></gf-form-switch>
</div>
<div class="gf-form" ng-if="ctrl.panel.yLabel.usingSplitLabel">
<label class="gf-form-label width-10">Delimiter
<info-popover mode="left-normal">
<p>Label splitter</p>
<span>
Set the string to split the original alias to generate partials to be used on the link and custom y-label
<span>
</info-popover>
</label>
<input type="text" class="gf-form-input width-10" placeholder="." data-placement="top"
ng-model="ctrl.panel.yLabel.delimiter" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
<div class="gf-form" ng-if="ctrl.panel.yLabel.usingSplitLabel">
<label class="gf-form-label width-10">Label template
<info-popover mode="left-normal">
<p>
<span>Override the series label</span>
<br>
<span> If blank, it will be used ${__y_label}</span>
</p>
<span>
Use special variables:
<br>
<em>${__y_label}</em> original name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
</span>
<span>
<hr>
<span>Examples</span>
<br>
<span>Series original:<em>"linux01.status.ok"</em></span>
<br>
<span>Separator: <em>"."</em></span>
<br>
<span>Label override:</span><em>${__y_label_1}-${__y_label_3} | ${__y_label_0}</em>
<br>
<span>Result: <em>status-ok | linux01</em></span>
</span>
</info-popover>
</label>
<input type="text" class="gf-form-input width-10" placeholder="${__y_label}" data-placement="top"
bs-tooltip="'Leave blank to use original ${__y_label}'" ng-model="ctrl.panel.yLabel.labelTemplate" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
<br>
<h5 class="section-heading">Pagination</h5>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Enable pagination" label-class="width-12"
+46 -3
View File
@@ -17,6 +17,45 @@
</gf-form-switch>
</div>
<div class="section gf-form-group">
<h5 class="section-heading">Custom content</h5>
<gf-form-switch class="gf-form" label-class="width-14"
label="Show custom content"
tooltip="'Show custom content on tooltip'"
checked="ctrl.panel.tooltip.showCustomContent" on-change="ctrl.render()">
</gf-form-switch>
<div class="gf-form" ng-if="ctrl.panel.tooltip.showCustomContent">
<label class="gf-form-label width-10">
Template
<info-popover mode="left-normal">
<p>Set custom content that will appear on the tooltip</p>
<span>
Use special variables:
<br>
<em>${__y_label}</em> name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
<br>
<em>${__url_time_range}</em> refers to graph range in the form of 'from=...&to=...'.
<br>
<em>${__value}</em> refers to current bucket value or max value if multiple values mode is on.
<br>
<em>${__value_N}</em> refers to Nth value in current bucket. Value indexes are started from 0. For instance,
<em>${__value_1}</em> refers to second value.
<br>
<em>${__value_date}</em> refers to __value formatted as date.
<em>${__value_N_date}</em> refers to Nth value in current bucket formatted as date.
</span>
</info-popover>
</label>
<textarea type="text" class="gf-form-input" placeholder="" data-placement="top" cols="100"
bs-tooltip="'Extra Tooltip info'" ng-model="ctrl.panel.tooltip.customContent" ng-change="ctrl.refresh()" ng-model-onblur> </textarea>
</div>
</div>
<br>
<div class="section gf-form-group">
<h5 class="section-heading">Items</h5>
@@ -24,9 +63,6 @@
<label class="gf-form-label width-2">0</label>
<label class="gf-form-input width-30">No items defined.</label>
</div>
</div>
</div>
<div>
<div ng-repeat="item in ctrl.panel.tooltip.items">
<div class="gf-form gf-form--grow">
@@ -39,6 +75,10 @@
<br>
<em>${__y_label}</em> name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
<br>
<em>${__url_time_range}</em> refers to graph range in the form of 'from=...&to=...'.
<br>
<em>${__value}</em> refers to current bucket value or max value if multiple values mode is on.
@@ -117,3 +157,6 @@
</div>
</div>
</div>
</div>
</div>
+4
View File
@@ -48,6 +48,8 @@ System.register([], function (_export, _context) {
_defineProperty(this, "yLabel", "");
_defineProperty(this, "pLabels", []);
_defineProperty(this, "x", 0);
_defineProperty(this, "xid", 0);
@@ -117,6 +119,8 @@ System.register([], function (_export, _context) {
_defineProperty(this, "targets", []);
_defineProperty(this, "pLabels", {});
_defineProperty(this, "rangeMs", 0);
_defineProperty(this, "intervalMs", 0);
+1 -1
View File
File diff suppressed because one or more lines are too long
+16 -3
View File
@@ -152,6 +152,7 @@ System.register(["d3", "jquery", "lodash"], function (_export, _context) {
var timestamp = bucket.to;
var yLabel = bucket.yLabel;
var pLabels = bucket.pLabels;
var value = bucket.value;
var values = bucket.values; // TODO create option for this formatting.
@@ -222,7 +223,14 @@ System.register(["d3", "jquery", "lodash"], function (_export, _context) {
scopedVars["__url_time_range"] = {
value: this.panelCtrl.retrieveTimeVar()
}; //New vars based on partialLabels:
for (var _i in pLabels) {
scopedVars["__y_label_".concat(_i)] = {
value: pLabels[_i]
};
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
@@ -242,10 +250,10 @@ System.register(["d3", "jquery", "lodash"], function (_export, _context) {
var valueDateVar = void 0;
for (var _i = 0; _i < bucket.values.length; _i++) {
valueDateVar = "__value_".concat(_i, "_date");
for (var _i2 = 0; _i2 < bucket.values.length; _i2++) {
valueDateVar = "__value_".concat(_i2, "_date");
scopedVars[valueDateVar] = {
value: this.dashboard.formatDate(+bucket.values[_i], dateFormat)
value: this.dashboard.formatDate(+bucket.values[_i2], dateFormat)
};
}
@@ -280,6 +288,11 @@ System.register(["d3", "jquery", "lodash"], function (_export, _context) {
}
}
if (this.panel.tooltip.showCustomContent) {
var customContent = this.panelCtrl.templateSrv.replace(this.panel.tooltip.customContent, scopedVars);
tooltipHtml += "<div>".concat(customContent, "</div>");
}
tooltipHtml += _.join(_.map(items, function (v) {
return "\n <div>\n <a href=\"".concat(v.link, "\" target=\"_blank\">\n <div class=\"dashlist-item\">\n <p class=\"dashlist-link dashlist-link-dash-db\">\n <span style=\"word-wrap: break-word;\" class=\"dash-title\">").concat(v.label, "</span><span class=\"dashlist-star\">\n <i class=\"fa fa-").concat(v.urlIcon, "\"></i>\n </span></p> </div></a><div>");
}), "\n");
+1 -1
View File
File diff suppressed because one or more lines are too long
+33 -1
View File
@@ -125,11 +125,18 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
show: true,
freezeOnClick: true,
showItems: false,
items: [] // see tooltip_editor.ts
items: [], // see tooltip_editor.ts
showExtraInfo: false,
extraInfo: "",
},
legend: {
show: true
},
yLabel: {
usingSplitLabel: false,
delimiter: "",
labelTemplate: "",
},
// how null points should be handled
nullPointMode: 'as empty',
yAxisSort: 'metrics',
@@ -526,6 +533,7 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
}
let targetIndex: {[target: string]: number[]} = {};
let targetPartials: {[target: string]: string[]} = {};
// Group indicies of elements in data by target (y label).
@@ -535,7 +543,29 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
//});
data.map((queryResult: any, i: number) => {
// Init yLabel as the query target
let yLabel = queryResult.target;
// Check if there is some labelTemplate configured
if (this.panel.yLabel.usingSplitLabel && this.panel.yLabel.delimiter != "" ) {
let pLabels = queryResult.target.split(this.panel.yLabel.delimiter);
// Load all possible values as scoped vars and load them into targetPartials
// to be used on different components as Bucket and BucketMatrix props
let scopedVars = []
scopedVars[`__y_label`] = {value: yLabel}
for (let i in pLabels) {
scopedVars[`__y_label_${i}`] = {value: pLabels[i]};
}
if (this.panel.yLabel.labelTemplate != "") {
yLabel = this.templateSrv.replace(this.panel.yLabel.labelTemplate, scopedVars)
}
targetPartials[yLabel] = pLabels
}
//reset if it already exists
if (!targetIndex.hasOwnProperty(yLabel)) {
targetIndex[yLabel] = [];
}
@@ -618,6 +648,7 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
while (bucketFrom >= 0) {
let b = new Bucket();
b.yLabel = target;
b.pLabels = targetPartials[target]
b.relTo = lastTs - idx*intervalMs;
b.relFrom = lastTs - ((idx+1) * intervalMs);
b.to = b.relTo+from;
@@ -681,6 +712,7 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
//console.log ("bucketMatrix with values: ", bucketMatrix);
bucketMatrix.targets = targetKeys;
bucketMatrix.pLabels = targetPartials;
return bucketMatrix;
}
}
+54
View File
@@ -215,6 +215,60 @@
</div>
<div class="section gf-form-group">
<h5 class="section-heading">Y-axis label</h5>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Split query alias" label-class="width-12"
checked="ctrl.panel.yLabel.usingSplitLabel" on-change="ctrl.refresh()"></gf-form-switch>
</div>
<div class="gf-form" ng-if="ctrl.panel.yLabel.usingSplitLabel">
<label class="gf-form-label width-10">Delimiter
<info-popover mode="left-normal">
<p>Label splitter</p>
<span>
Set the string to split the original alias to generate partials to be used on the link and custom y-label
<span>
</info-popover>
</label>
<input type="text" class="gf-form-input width-10" placeholder="." data-placement="top"
ng-model="ctrl.panel.yLabel.delimiter" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
<div class="gf-form" ng-if="ctrl.panel.yLabel.usingSplitLabel">
<label class="gf-form-label width-10">Label template
<info-popover mode="left-normal">
<p>
<span>Override the series label</span>
<br>
<span> If blank, it will be used ${__y_label}</span>
</p>
<span>
Use special variables:
<br>
<em>${__y_label}</em> original name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
</span>
<span>
<hr>
<span>Examples</span>
<br>
<span>Series original:<em>"linux01.status.ok"</em></span>
<br>
<span>Separator: <em>"."</em></span>
<br>
<span>Label override:</span><em>${__y_label_1}-${__y_label_3} | ${__y_label_0}</em>
<br>
<span>Result: <em>status-ok | linux01</em></span>
</span>
</info-popover>
</label>
<input type="text" class="gf-form-input width-10" placeholder="${__y_label}" data-placement="top"
bs-tooltip="'Leave blank to use original ${__y_label}'" ng-model="ctrl.panel.yLabel.labelTemplate" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
<br>
<h5 class="section-heading">Pagination</h5>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Enable pagination" label-class="width-12"
+46 -3
View File
@@ -17,6 +17,45 @@
</gf-form-switch>
</div>
<div class="section gf-form-group">
<h5 class="section-heading">Custom content</h5>
<gf-form-switch class="gf-form" label-class="width-14"
label="Show custom content"
tooltip="'Show custom content on tooltip'"
checked="ctrl.panel.tooltip.showCustomContent" on-change="ctrl.render()">
</gf-form-switch>
<div class="gf-form" ng-if="ctrl.panel.tooltip.showCustomContent">
<label class="gf-form-label width-10">
Template
<info-popover mode="left-normal">
<p>Set custom content that will appear on the tooltip</p>
<span>
Use special variables:
<br>
<em>${__y_label}</em> name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
<br>
<em>${__url_time_range}</em> refers to graph range in the form of 'from=...&to=...'.
<br>
<em>${__value}</em> refers to current bucket value or max value if multiple values mode is on.
<br>
<em>${__value_N}</em> refers to Nth value in current bucket. Value indexes are started from 0. For instance,
<em>${__value_1}</em> refers to second value.
<br>
<em>${__value_date}</em> refers to __value formatted as date.
<em>${__value_N_date}</em> refers to Nth value in current bucket formatted as date.
</span>
</info-popover>
</label>
<textarea type="text" class="gf-form-input" placeholder="" data-placement="top" cols="100"
bs-tooltip="'Extra Tooltip info'" ng-model="ctrl.panel.tooltip.customContent" ng-change="ctrl.refresh()" ng-model-onblur> </textarea>
</div>
</div>
<br>
<div class="section gf-form-group">
<h5 class="section-heading">Items</h5>
@@ -24,9 +63,6 @@
<label class="gf-form-label width-2">0</label>
<label class="gf-form-input width-30">No items defined.</label>
</div>
</div>
</div>
<div>
<div ng-repeat="item in ctrl.panel.tooltip.items">
<div class="gf-form gf-form--grow">
@@ -39,6 +75,10 @@
<br>
<em>${__y_label}</em> name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_trim}</em> trimmed name of the time series (alias or legend in the query editor).
<br>
<em>${__y_label_N}</em> partial name of the time series (alias or legend in the query editor), only valid when custom y-label is enabled.
<br>
<em>${__url_time_range}</em> refers to graph range in the form of 'from=...&to=...'.
<br>
<em>${__value}</em> refers to current bucket value or max value if multiple values mode is on.
@@ -117,3 +157,6 @@
</div>
</div>
</div>
</div>
</div>
+3
View File
@@ -12,6 +12,8 @@ class Bucket {
// y label
y: string = "";
yLabel: string = "";
pLabels: string[] = [];
// This value can be used to calculate a x coordinate on a graph
x: number = 0;
xid: number = 0;
@@ -64,6 +66,7 @@ class BucketMatrix {
// An array of row labels
targets: string[] = [];
pLabels: {[target: string]: string[]} = {};
rangeMs: number = 0;
intervalMs: number = 0;
+11
View File
@@ -112,6 +112,7 @@ export class StatusmapTooltip {
let timestamp = bucket.to;
let yLabel = bucket.yLabel;
let pLabels = bucket.pLabels;
let value = bucket.value;
let values = bucket.values;
// TODO create option for this formatting.
@@ -188,6 +189,11 @@ export class StatusmapTooltip {
// Grafana 7.0 compatible
scopedVars[`__url_time_range`] = {value: this.panelCtrl.retrieveTimeVar()};
//New vars based on partialLabels:
for (let i in pLabels) {
scopedVars[`__y_label_${i}`] = {value: pLabels[i]};
}
for (let item of items) {
if (_.isEmpty(item.urlTemplate)) {
item.link = "#";
@@ -217,6 +223,11 @@ export class StatusmapTooltip {
}
}
if (this.panel.tooltip.showCustomContent) {
let customContent: string = this.panelCtrl.templateSrv.replace(this.panel.tooltip.customContent, scopedVars)
tooltipHtml += `<div>${customContent}</div>`
}
tooltipHtml += _.join(_.map(items, v => `
<div>
<a href="${v.link}" target="_blank">