Added YLabel splitter and Extra info on tooltip

Actually, custom label are not allowed, it directly uses the provided by
the query result as the target/alias

This feature allows to:

- Split YLabel to store its partials and reuse them on link and extra tooltip field
- Override YLabel with splitted and custom values
- Added Extra Tooltip to show metadata to the user on each serie
This commit is contained in:
sbengo
2020-12-02 16:41:18 +01:00
parent a7a82ff3f5
commit fa80d4a3dc
13 changed files with 309 additions and 18 deletions
+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">