feat: pagination

Continuation of PR #93.

- reworked layout for pagination controls on graph
- use BucketMatrixPager for pagination logic and state
This commit is contained in:
Ivan Mikheykin
2020-07-13 21:31:14 +03:00
parent 99ba3cbdd6
commit ef4b0e1228
28 changed files with 469 additions and 1153 deletions
+9
View File
@@ -69,6 +69,15 @@
.width-c-70 { .width-c-70 {
width: 70rem !important; } width: 70rem !important; }
.statusmap-pagination {
margin-top: 5px; }
.statusmap-pagination label {
margin-right: 0px; }
.statusmap-pagination input {
margin-right: 0px; }
.statusmap-pagination .last-in-group {
margin-right: 4px; }
.pagination-buttons { .pagination-buttons {
text-align: right; } text-align: right; }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAGjB,kDAAoB;IAClB,cAAc,EAAE,IAAI;EAGtB,uDAAyB;IACzB,gBAAgB,ECNL,OAAO;IDOlB,KAAK,ECVM,OAAO;IDWlB,OAAO,EAAE,GAAG;;AAId,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAGhB,iCAAK;IACH,IAAI,ECpBG,OAAO;IDqBd,KAAK,ECrBE,OAAO;IDsBd,SAAS,EEtBE,IAAI;EFyBjB,iCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC1BM,OAAO;ED+BvB,oBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,yBAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EAGjB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,GAAG;EAClB,SAAS,EAAE,KAAK;EAChB,UAAU,EAAE,KAAK;EACjB,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,IAAI;EAGb,WAAW,EAAE,MAAM;EACnB,SAAS,EEzDI,IAAI;EF0DjB,gBAAgB,ECvDC,OAAO;EDwDxB,KAAK,EC1DM,OAAO;ED4DlB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,uDAAuD;;AAIxE,yBAA0B;EACxB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;;AAGZ,yBAA0B;EACxB,IAAI,ECzEY,OAAO;;AD6EvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AAEA,mBAAmB;EAAC,UAAU,EAAE,KAAK;;AAErC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EC7HG,OAAO;ID8Hd,KAAK,EC9HE,OAAO;ID+Hd,SAAS,EE/HE,IAAI;EFkIjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECnIM,OAAO;EDsIrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECxIM,OAAO", "mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAGjB,kDAAoB;IAClB,cAAc,EAAE,IAAI;EAGtB,uDAAyB;IACzB,gBAAgB,ECNL,OAAO;IDOlB,KAAK,ECVM,OAAO;IDWlB,OAAO,EAAE,GAAG;;AAId,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAGhB,iCAAK;IACH,IAAI,ECpBG,OAAO;IDqBd,KAAK,ECrBE,OAAO;IDsBd,SAAS,EEtBE,IAAI;EFyBjB,iCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC1BM,OAAO;ED+BvB,oBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,yBAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EAGjB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,GAAG;EAClB,SAAS,EAAE,KAAK;EAChB,UAAU,EAAE,KAAK;EACjB,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,IAAI;EAGb,WAAW,EAAE,MAAM;EACnB,SAAS,EEzDI,IAAI;EF0DjB,gBAAgB,ECvDC,OAAO;EDwDxB,KAAK,EC1DM,OAAO;ED4DlB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,uDAAuD;;AAIxE,yBAA0B;EACxB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;;AAGZ,yBAA0B;EACxB,IAAI,ECzEY,OAAO;;AD6EvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AAEA,qBAAsB;EAEpB,UAAU,EAAE,GAAG;EACf,2BAAM;IACJ,YAAY,EAAC,GAAG;EAElB,2BAAM;IACJ,YAAY,EAAE,GAAG;EAEnB,oCAAe;IACb,YAAY,EAAE,GAAG;;AAIrB,mBAAmB;EAAC,UAAU,EAAE,KAAK;;AAErC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EC3IG,OAAO;ID4Id,KAAK,EC5IE,OAAO;ID6Id,SAAS,EE7IE,IAAI;EFgJjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECjJM,OAAO;EDoJrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECtJM,OAAO",
"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.dark.scss","../../src/css/_variables.scss"], "sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.dark.scss","../../src/css/_variables.scss"],
"names": [], "names": [],
"file": "statusmap.dark.css" "file": "statusmap.dark.css"
+9
View File
@@ -69,6 +69,15 @@
.width-c-70 { .width-c-70 {
width: 70rem !important; } width: 70rem !important; }
.statusmap-pagination {
margin-top: 5px; }
.statusmap-pagination label {
margin-right: 0px; }
.statusmap-pagination input {
margin-right: 0px; }
.statusmap-pagination .last-in-group {
margin-right: 4px; }
.pagination-buttons { .pagination-buttons {
text-align: right; } text-align: right; }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAGjB,kDAAoB;IAClB,cAAc,EAAE,IAAI;EAGtB,uDAAyB;IACzB,gBAAgB,ECNL,OAAO;IDOlB,KAAK,ECVM,OAAO;IDWlB,OAAO,EAAE,GAAG;;AAId,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAGhB,iCAAK;IACH,IAAI,ECpBG,OAAO;IDqBd,KAAK,ECrBE,OAAO;IDsBd,SAAS,EEtBE,IAAI;EFyBjB,iCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC1BM,OAAO;ED+BvB,oBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,yBAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EAGjB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,GAAG;EAClB,SAAS,EAAE,KAAK;EAChB,UAAU,EAAE,KAAK;EACjB,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,IAAI;EAGb,WAAW,EAAE,MAAM;EACnB,SAAS,EEzDI,IAAI;EF0DjB,gBAAgB,ECvDC,OAAO;EDwDxB,KAAK,EC1DM,OAAO;ED4DlB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,uDAAuD;;AAIxE,yBAA0B;EACxB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;;AAGZ,yBAA0B;EACxB,IAAI,ECzEY,OAAO;;AD6EvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AAEA,mBAAmB;EAAC,UAAU,EAAE,KAAK;;AAErC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EC7HG,OAAO;ID8Hd,KAAK,EC9HE,OAAO;ID+Hd,SAAS,EE/HE,IAAI;EFkIjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECnIM,OAAO;EDsIrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECxIM,OAAO", "mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAGjB,kDAAoB;IAClB,cAAc,EAAE,IAAI;EAGtB,uDAAyB;IACzB,gBAAgB,ECNL,OAAO;IDOlB,KAAK,ECVM,OAAO;IDWlB,OAAO,EAAE,GAAG;;AAId,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAGhB,iCAAK;IACH,IAAI,ECpBG,OAAO;IDqBd,KAAK,ECrBE,OAAO;IDsBd,SAAS,EEtBE,IAAI;EFyBjB,iCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC1BM,OAAO;ED+BvB,oBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,yBAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EAGjB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,GAAG;EAClB,SAAS,EAAE,KAAK;EAChB,UAAU,EAAE,KAAK;EACjB,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,IAAI;EAGb,WAAW,EAAE,MAAM;EACnB,SAAS,EEzDI,IAAI;EF0DjB,gBAAgB,ECvDC,OAAO;EDwDxB,KAAK,EC1DM,OAAO;ED4DlB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,uDAAuD;;AAIxE,yBAA0B;EACxB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;;AAGZ,yBAA0B;EACxB,IAAI,ECzEY,OAAO;;AD6EvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AACA,WAAY;EACV,KAAK,EAAE,gBACT;;AAEA,qBAAsB;EAEpB,UAAU,EAAE,GAAG;EACf,2BAAM;IACJ,YAAY,EAAC,GAAG;EAElB,2BAAM;IACJ,YAAY,EAAE,GAAG;EAEnB,oCAAe;IACb,YAAY,EAAE,GAAG;;AAIrB,mBAAmB;EAAC,UAAU,EAAE,KAAK;;AAErC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EC3IG,OAAO;ID4Id,KAAK,EC5IE,OAAO;ID6Id,SAAS,EE7IE,IAAI;EFgJjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECjJM,OAAO;EDoJrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECtJM,OAAO",
"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.light.scss","../../src/css/_variables.scss"], "sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.light.scss","../../src/css/_variables.scss"],
"names": [], "names": [],
"file": "statusmap.light.css" "file": "statusmap.light.css"
-28
View File
@@ -1,28 +0,0 @@
"use strict";
System.register([], function (_export, _context) {
"use strict";
var ExtraSeriesFormat, ExtraSeriesFormatValue;
_export({
ExtraSeriesFormat: void 0,
ExtraSeriesFormatValue: void 0
});
return {
setters: [],
execute: function () {
(function (ExtraSeriesFormat) {
ExtraSeriesFormat["Date"] = "Date";
ExtraSeriesFormat["Raw"] = "Raw";
})(ExtraSeriesFormat || _export("ExtraSeriesFormat", ExtraSeriesFormat = {}));
(function (ExtraSeriesFormatValue) {
ExtraSeriesFormatValue["Date"] = "YYYY/MM/DD/HH_mm_ss";
ExtraSeriesFormatValue["Raw"] = "";
})(ExtraSeriesFormatValue || _export("ExtraSeriesFormatValue", ExtraSeriesFormatValue = {}));
}
};
});
//# sourceMappingURL=extra_series_format.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["../src/extra_series_format.ts"],"names":["ExtraSeriesFormat","ExtraSeriesFormatValue"],"mappings":";;;;;;;;;;;;;;;iBAAYA,iB;AAAAA,QAAAA,iB;AAAAA,QAAAA,iB;SAAAA,iB,iCAAAA,iB;;iBAKAC,sB;AAAAA,QAAAA,sB;AAAAA,QAAAA,sB;SAAAA,sB,sCAAAA,sB","sourcesContent":["export enum ExtraSeriesFormat {\n Date = 'Date',\n Raw = 'Raw',\n}\n\nexport enum ExtraSeriesFormatValue {\n Date = 'YYYY/MM/DD/HH_mm_ss',\n Raw = '',\n}"],"file":"extra_series_format.js"}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 34 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+24 -24
View File
@@ -1,37 +1,37 @@
<div class="status-heatmap-wrapper"> <div class="status-heatmap-wrapper">
<div class="clearfix"></div>
<br>
<div class="gf-form" ng-if="ctrl.panel.usingPagination">
<label class="gf-form-label width-9">Items per page</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right"
bs-tooltip="'Number of items to show per page.'" ng-model="ctrl.pageSizeViewer" ng-change="ctrl.changePaginationSize()"
ng-model-onblur>
</div>
<div class="status-heatmap-canvas-wrapper"> <div class="status-heatmap-canvas-wrapper">
<div class="datapoints-warning" ng-if="ctrl.multipleValues || ctrl.noColorDefined || ctrl.noDatapoints"> <div class="datapoints-warning" ng-if="ctrl.multipleValues || ctrl.noColorDefined || ctrl.noDatapoints">
<span class="small" ng-if="ctrl.multipleValues" bs-tooltip="'{{ctrl.dataWarnings.multipleValues.tip}}'">{{ctrl.dataWarnings.multipleValues.title}}</span> <span class="small" ng-if="ctrl.multipleValues" bs-tooltip="'{{ctrl.dataWarnings.multipleValues.tip}}'">{{ctrl.dataWarnings.multipleValues.title}}</span>
<span class="small" ng-if="ctrl.noColorDefined" bs-tooltip="'{{ctrl.dataWarnings.noColorDefined.tip}}'">{{ctrl.dataWarnings.noColorDefined.title}}</span> <span class="small" ng-if="ctrl.noColorDefined" bs-tooltip="'{{ctrl.dataWarnings.noColorDefined.tip}}'">{{ctrl.dataWarnings.noColorDefined.title}}</span>
<span class="small" ng-if="ctrl.noDatapoints" bs-tooltip="'{{ctrl.dataWarnings.noDatapoints.tip}}'">{{ctrl.dataWarnings.noDatapoints.title}}</span> <span class="small" ng-if="ctrl.noDatapoints" bs-tooltip="'{{ctrl.dataWarnings.noDatapoints.tip}}'">{{ctrl.dataWarnings.noDatapoints.title}}</span>
</div> </div>
<div class="statusmap-panel" ng-dblclick="ctrl.zoomOut()"></div>
</div>
<div class="status-heatmap-panel" ng-dblclick="ctrl.zoomOut()"></div>
</div>
<div class="pagination" ng-if="ctrl.panel.usingPagination">
Showing {{ctrl.firstPageElement}} to {{ctrl.lastPageElement}} of {{ctrl.totalElements}} entries
<div class="pagination-buttons">
<button class="btn btn-inverse" ng-disabled="ctrl.currentPage == 0" ng-click="ctrl.currentPage=ctrl.currentPage-1; ctrl.render()">
Previous
</button>
{{ctrl.currentPage+1}}/{{ctrl.numberOfPages}}
<button class="btn btn-inverse" ng-disabled="ctrl.currentPage >= ctrl.cardsData.targets.length/ctrl.pageSizeViewer - 1 || ctrl.numberOfPages == 0" ng-click="ctrl.currentPage=ctrl.currentPage+1; ctrl.render()">
Next
</button>
</div>
</div>
<div class="status-heatmap-legend-wrapper" ng-if="ctrl.panel.legend.show"> <div class="status-heatmap-legend-wrapper" ng-if="ctrl.panel.legend.show">
<status-heatmap-legend></status-heatmap-legend> <status-heatmap-legend></status-heatmap-legend>
</div> </div>
<div class="clearfix"></div>
<div class="statusmap-pagination gf-form" ng-if="ctrl.panel.usingPagination">
<div class="gf-form">
<button class="btn btn-inverse" ng-disabled="!pager.hasPrev()" ng-click="ctrl.onPrevPage()">
<i class="fa fa-arrow-left"></i>&nbsp;Previous
</button>
<label class="gf-form-label">{{pager.currentPage+1}}/{{pager.pages()}}</label>
<button class="btn btn-inverse last-in-group" ng-disabled="!pager.hasNext()" ng-click="ctrl.onNextPage()">
Next&nbsp;<i class="fa fa-arrow-right"></i>
</button>
</div>
<div class="gf-form">
<label class="gf-form-label">Rows per page</label>
<input type="number" class="gf-form-input width-3 last-in-group" placeholder="12" data-placement="top"
bs-tooltip="'Number of rows to show per page.'" ng-model="ctrl.pageSizeViewer" ng-change="ctrl.onChangePageSize()"
ng-model-onblur>
</div>
<label class="gf-form-label">Show {{pager.pageStartRow()}} to {{pager.pageEndRow()}} of {{pager.totalRows()}} rows</label>
</div>
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
+40 -93
View File
@@ -3,7 +3,7 @@
System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_editor", "./panel_config_migration", "app/core/utils/kbn", "app/plugins/sdk", "./libs/grafana/events/index", "./statusmap_data", "./rendering", "./libs/polygrafill/index", "./color_mode_discrete"], function (_export, _context) { System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_editor", "./panel_config_migration", "app/core/utils/kbn", "app/plugins/sdk", "./libs/grafana/events/index", "./statusmap_data", "./rendering", "./libs/polygrafill/index", "./color_mode_discrete"], function (_export, _context) {
"use strict"; "use strict";
var _, optionsEditorCtrl, tooltipEditorCtrl, migratePanelConfig, kbn, loadPluginCss, MetricsPanelCtrl, CoreEvents, PanelEvents, Bucket, BucketMatrix, rendering, Polygrafill, ColorModeDiscrete, VALUE_INDEX, TIME_INDEX, colorSchemes, colorModes, opacityScales, renderComplete, StatusHeatmapCtrl; var _, optionsEditorCtrl, tooltipEditorCtrl, migratePanelConfig, kbn, loadPluginCss, MetricsPanelCtrl, CoreEvents, PanelEvents, Bucket, BucketMatrix, BucketMatrixPager, rendering, Polygrafill, ColorModeDiscrete, VALUE_INDEX, TIME_INDEX, colorSchemes, colorModes, opacityScales, renderComplete, StatusHeatmapCtrl;
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
@@ -49,6 +49,7 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
}, function (_statusmap_data) { }, function (_statusmap_data) {
Bucket = _statusmap_data.Bucket; Bucket = _statusmap_data.Bucket;
BucketMatrix = _statusmap_data.BucketMatrix; BucketMatrix = _statusmap_data.BucketMatrix;
BucketMatrixPager = _statusmap_data.BucketMatrixPager;
}, function (_rendering) { }, function (_rendering) {
rendering = _rendering.default; rendering = _rendering.default;
}, function (_libsPolygrafillIndex) { }, function (_libsPolygrafillIndex) {
@@ -166,6 +167,8 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_inherits(StatusHeatmapCtrl, _MetricsPanelCtrl); _inherits(StatusHeatmapCtrl, _MetricsPanelCtrl);
// TODO remove this transient variable: use ng-model-options="{ getterSetter: true }"
/** @ngInject */ /** @ngInject */
function StatusHeatmapCtrl($scope, $injector, timeSrv, annotationsSrv, $window, datasourceSrv, variableSrv, templateSrv) { function StatusHeatmapCtrl($scope, $injector, timeSrv, annotationsSrv, $window, datasourceSrv, variableSrv, templateSrv) {
var _this; var _this;
@@ -180,6 +183,8 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_defineProperty(_assertThisInitialized(_this), "bucketMatrix", void 0); _defineProperty(_assertThisInitialized(_this), "bucketMatrix", void 0);
_defineProperty(_assertThisInitialized(_this), "bucketMatrixPager", void 0);
_defineProperty(_assertThisInitialized(_this), "graph", void 0); _defineProperty(_assertThisInitialized(_this), "graph", void 0);
_defineProperty(_assertThisInitialized(_this), "discreteHelper", void 0); _defineProperty(_assertThisInitialized(_this), "discreteHelper", void 0);
@@ -192,12 +197,6 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_defineProperty(_assertThisInitialized(_this), "unitFormats", void 0); _defineProperty(_assertThisInitialized(_this), "unitFormats", void 0);
_defineProperty(_assertThisInitialized(_this), "cardsDataComplete", void 0);
_defineProperty(_assertThisInitialized(_this), "cardsDataLabelsComplete", void 0);
_defineProperty(_assertThisInitialized(_this), "ticksWhenPaginating", void 0);
_defineProperty(_assertThisInitialized(_this), "dataWarnings", {}); _defineProperty(_assertThisInitialized(_this), "dataWarnings", {});
_defineProperty(_assertThisInitialized(_this), "multipleValues", void 0); _defineProperty(_assertThisInitialized(_this), "multipleValues", void 0);
@@ -214,16 +213,6 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_defineProperty(_assertThisInitialized(_this), "pageSizeViewer", 15); _defineProperty(_assertThisInitialized(_this), "pageSizeViewer", 15);
_defineProperty(_assertThisInitialized(_this), "currentPage", 0);
_defineProperty(_assertThisInitialized(_this), "numberOfPages", 1);
_defineProperty(_assertThisInitialized(_this), "totalElements", 0);
_defineProperty(_assertThisInitialized(_this), "firstPageElement", 1);
_defineProperty(_assertThisInitialized(_this), "lastPageElement", 5);
_defineProperty(_assertThisInitialized(_this), "panelDefaults", { _defineProperty(_assertThisInitialized(_this), "panelDefaults", {
// datasource name, null = default datasource // datasource name, null = default datasource
datasource: null, datasource: null,
@@ -270,10 +259,9 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
highlightCards: true, highlightCards: true,
useMax: true, useMax: true,
seriesFilterIndex: -1, seriesFilterIndex: -1,
// Pagination options
usingPagination: false, usingPagination: false,
pageSize: 15, pageSize: 15
allowAllElements: false,
availableValues: []
}); });
if (!Polygrafill.hasAppEventCompatibleEmitter(_this.events)) { if (!Polygrafill.hasAppEventCompatibleEmitter(_this.events)) {
@@ -287,12 +275,17 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_.defaultsDeep(_this.panel, _this.panelDefaults); _.defaultsDeep(_this.panel, _this.panelDefaults);
if (_this.panel.usingPagination) { _this.bucketMatrix = new BucketMatrix(); // Create pager for bucketMatrix and restore page size.
_this.setPaginationSize(_this.panel.pageSize);
_this.setCurrentPage(0); _this.bucketMatrixPager = new BucketMatrixPager();
}
_this.bucketMatrixPager.setEnable(_this.panel.usingPagination);
_this.bucketMatrixPager.setDefaultPageSize(_this.panel.pageSize);
_this.bucketMatrixPager.setPageSize(_this.panel.pageSize);
$scope.pager = _this.bucketMatrixPager;
_this.opacityScales = opacityScales; _this.opacityScales = opacityScales;
_this.colorModes = colorModes; _this.colorModes = colorModes;
_this.colorSchemes = colorSchemes; // default graph width for discrete card width calculation _this.colorSchemes = colorSchemes; // default graph width for discrete card width calculation
@@ -349,75 +342,35 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
}, { }, {
key: "changeDefaultPaginationSize", key: "changeDefaultPaginationSize",
value: function changeDefaultPaginationSize(defaultPageSize) { value: function changeDefaultPaginationSize(defaultPageSize) {
this.bucketMatrixPager.setDefaultPageSize(defaultPageSize);
this.bucketMatrixPager.setPageSize(defaultPageSize);
this.pageSizeViewer = defaultPageSize; this.pageSizeViewer = defaultPageSize;
this.render(); this.render();
this.refresh(); this.refresh();
} }
}, { }, {
key: "changePaginationSize", key: "onChangePageSize",
value: function changePaginationSize() { value: function onChangePageSize() {
if (this.pageSizeViewer <= 0) { if (this.pageSizeViewer <= 0) {
this.pageSizeViewer = 1; this.pageSizeViewer = this.bucketMatrixPager.defaultPageSize;
} }
this.currentPage = 0; this.bucketMatrixPager.setPageSize(this.pageSizeViewer);
this.bucketMatrixPager.setCurrent(0);
this.render(); this.render();
this.refresh(); this.refresh();
} }
}, { }, {
key: "getPaginationSize", key: "onPrevPage",
value: function getPaginationSize() { value: function onPrevPage() {
return this.pageSizeViewer; this.bucketMatrixPager.switchToPrev();
this.render();
} }
}, { }, {
key: "setPaginationSize", key: "onNextPage",
value: function setPaginationSize(pageSize) { value: function onNextPage() {
this.pageSizeViewer = pageSize; this.bucketMatrixPager.switchToNext();
} this.render();
}, {
key: "getCurrentPage",
value: function getCurrentPage() {
return this.currentPage;
}
}, {
key: "setCurrentPage",
value: function setCurrentPage(currentPage) {
this.currentPage = currentPage;
}
}, {
key: "getNumberOfPages",
value: function getNumberOfPages() {
return this.numberOfPages;
}
}, {
key: "getTotalElements",
value: function getTotalElements() {
return this.totalElements;
}
}, {
key: "setTotalElements",
value: function setTotalElements(totalElements) {
this.totalElements = totalElements;
}
}, {
key: "getFirstPageElement",
value: function getFirstPageElement() {
return this.firstPageElement;
}
}, {
key: "setFirstPageElement",
value: function setFirstPageElement(firstPageElement) {
this.firstPageElement = firstPageElement;
}
}, {
key: "getLastPageElement",
value: function getLastPageElement() {
return this.lastPageElement;
}
}, {
key: "setLastPageElement",
value: function setLastPageElement(lastPageElement) {
this.lastPageElement = lastPageElement;
} // getChartWidth returns an approximation of chart canvas width or } // getChartWidth returns an approximation of chart canvas width or
// a saved value calculated during a render. // a saved value calculated during a render.
@@ -546,16 +499,16 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
this.calculateInterval(); this.calculateInterval();
} }
this.bucketMatrix = this.convertDataToBuckets(dataList, this.range.from.valueOf(), this.range.to.valueOf(), this.intervalMs, true); var newBucketMatrix = this.convertDataToBuckets(dataList, this.range.from.valueOf(), this.range.to.valueOf(), this.intervalMs, true);
this.noDatapoints = this.bucketMatrix.noDatapoints; this.bucketMatrix = newBucketMatrix;
this.bucketMatrixPager.bucketMatrix = newBucketMatrix;
if (this.panel.usingPagination && this.cardsData.targets) { if (newBucketMatrix.targets.length !== this.bucketMatrix.targets.length) {
this.numberOfPages = Math.ceil(this.cardsData.targets.length / this.pageSizeViewer); this.bucketMatrixPager.setCurrent(0);
this.totalElements = this.cardsData.targets.length;
} else {
this.setPaginationSize(this.cardsData.targets.length);
} }
this.noDatapoints = this.bucketMatrix.noDatapoints;
if (this.annotationsPromise) { if (this.annotationsPromise) {
this.annotationsPromise.then(function (result) { this.annotationsPromise.then(function (result) {
_this3.loading = false; //this.alertState = result.alertState; _this3.loading = false; //this.alertState = result.alertState;
@@ -571,8 +524,7 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
_this3.loading = false; _this3.loading = false;
_this3.annotations = []; _this3.annotations = [];
_this3.render(); // this.render(this.data);??? _this3.render();
}); });
} else { } else {
this.loading = false; this.loading = false;
@@ -586,11 +538,6 @@ System.register(["lodash", "./color_legend", "./options_editor", "./tooltip_edit
this.addEditorTab('Options', optionsEditorCtrl, 2); this.addEditorTab('Options', optionsEditorCtrl, 2);
this.addEditorTab('Tooltip', tooltipEditorCtrl, 3); this.addEditorTab('Tooltip', tooltipEditorCtrl, 3);
this.unitFormats = kbn.getUnitFormats(); this.unitFormats = kbn.getUnitFormats();
}
}, {
key: "paginate",
value: function paginate() {
this.refresh();
} // onRender will be called before StatusmapRenderer.onRender. } // onRender will be called before StatusmapRenderer.onRender.
// Decide if warning should be displayed over cards. // Decide if warning should be displayed over cards.
+1 -1
View File
File diff suppressed because one or more lines are too long
+6 -107
View File
@@ -216,119 +216,18 @@
</div> </div>
</div> </div>
<div class="section gf-form-group width-30">
<h5 class="section-heading">Filtering</h5>
<div class="gf-form">
<label class="gf-form-label width-9">Show only serie with Index</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right"
bs-tooltip="'Filter with the serie index to show the value on graph. Use -1 to get all values'" ng-model="ctrl.panel.seriesFilterIndex" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
</div>
<div class="section gf-form-group"> <div class="section gf-form-group">
<h5 class="section-heading">Pagination options</h5> <h5 class="section-heading">Pagination</h5>
<div class="gf-form"> <div class="gf-form">
<gf-form-switch class="gf-form" label="Paginate elements" label-class="width-12" <gf-form-switch class="gf-form" label="Enable pagination" label-class="width-12"
checked="ctrl.panel.usingPagination" on-change="ctrl.paginate()"></gf-form-switch> checked="ctrl.panel.usingPagination" on-change="ctrl.render()"></gf-form-switch>
</div> </div>
<div class="gf-form" ng-if="ctrl.panel.usingPagination"> <div class="gf-form" ng-if="ctrl.panel.usingPagination">
<label class="gf-form-label width-9">Items per Page by default</label> <label class="gf-form-label width-10">Rows per page</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right" <input type="number" class="gf-form-input width-5" placeholder="2" data-placement="top"
bs-tooltip="Number of items to show by default" ng-model="ctrl.panel.pageSize" ng-change="ctrl.changeDefaultPaginationSize(ctrl.panel.pageSize)" bs-tooltip="'Number of rows to show by default'" ng-model="ctrl.panel.pageSize" ng-change="ctrl.changeDefaultPaginationSize(ctrl.panel.pageSize)"
ng-model-onblur> ng-model-onblur>
</div> </div>
</div> </div>
<div class="section gf-form-group">
<h5 class="section-heading">URL</h5>
<div class="gf-form">
Insert the url to navigate<br />
</div>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Show extraSeries Tooltip when clicking elements" label-class="width-12"
checked="ctrl.panel.usingUrl" on-change="ctrl.render()"></gf-form-switch>
</div>
<div class="section gf-form-group" ng-if="ctrl.panel.usingUrl">
<br>
<div class="gf-form-inline">
<div class="gf-form"></div>
<div class="gf-form">
<button class="btn btn-inverse" ng-click="ctrl.onEditorAddUrl()">
<i class="fa fa-plus"></i> Add new URL
</button>
</div>
<div class="gf-form">
<button class="btn btn-inverse" ng-click="ctrl.onEditorRemoveUrls()">
<i class="fa fa-minus"></i> Remove all URLs
</button>
</div>
</div>
<div class="gf-form-block" ng-repeat="url in ctrl.panel.urls">
<div class="gf-form">
<label class="gf-form-label width-2">{{ $index }}</label>
<label class="gf-form-label width-2">
<a class="pointer" tabindex="1" ng-click="ctrl.onEditorRemoveUrl($index)">
<i class="fa fa-trash" />
</a>
</label>
<label class="gf-form-label width-4">Label: </label>
<input type="text" class="gf-form-input width-16" placeholder="My URL" data-placement="right"
ng-model="url.label" ng-change="ctrl.refresh()">
<label class="gf-form-label width-4">URL: </label>
<input type="text" class="gf-form-input width-c-50" placeholder="https://www.google.es" data-placement="right"
bs-tooltip="'This is the url to be shown when the user clicks on it'" ng-model="url.base_url"
ng-change="ctrl.refresh()">
<info-popover mode="right-normal">
<p>Specify an URL (relative or absolute)</p>
<span>
Use special variables to specify cell values:
<br>
<em>$series_label</em> name of the serie
<br>
<em>$(template.name)</em> name of the templated to be replaced
<br>
<em>$time</em> append &from...&to on the URL
<br>
<em>$series_extra</em> use extraSeries value to use it on URL
</span>
</info-popover>
</div>
<div class="gf-form">
<label class="gf-form-label width-4">Icon: </label>
<input type="text" class="gf-form-input width-12" placeholder="FA Icon" data-placement="right"
bs-tooltip="'The icon shown on URL'" ng-model="url.icon_fa" ng-change="ctrl.refresh()">
<gf-form-switch class="gf-form" label-class="width-8" label="Force lowercase" checked="url.forcelowercase"
on-change="ctrl.render()">
</gf-form-switch>
<gf-form-switch class="gf-form" label-class="width-6" label="Use Extra Serie Data" checked="url.useExtraSeries"
on-change="ctrl.render()">
</gf-form-switch>
<div class="gf-form" ng-if="url.useExtraSeries == true">
<label class="gf-form-label width-8">Extra Series Index: </label>
<input type="number" class="gf-form-input width-12" placeholder="0" ng-if="url.useExtraSeries == true"
data-placement="right" bs-tooltip="'Fields index to use its value on URL using $series_extra. Use -1 to disable it'" ng-model="url.extraSeries.index"
ng-change="ctrl.refresh()">
<label class="gf-form-label width-9">Type</label>
<div class="gf-form-select-wrapper width-8">
<select class="input-small gf-form-input" ng-model="url.type" ng-options="s for s in ctrl.extraSeriesFormats" ng-change="ctrl.onChangeType(url)"></select>
</div>
<div ng-if="url.type === 'Date'">
<label class="gf-form-label width-12">Extra Series Date Format: </label>
<input type="text" class="gf-form-input width-12" placeholder="YYYY/MM/DD/HH_mm_ss" ng-if="url.useExtraSeries == true"
data-placement="right" bs-tooltip="'Date format to transformat extraSeries'" ng-model="url.extraSeries.format"
ng-change="ctrl.refresh()">
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
+17 -100
View File
@@ -5,14 +5,6 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
var _, $, moment, kbn, appEvents, contextSrv, d3, d3ScaleChromatic, StatusmapTooltip, AnnotationTooltip, renderComplete, CoreEvents, PanelEvents, MIN_CARD_SIZE, CARD_H_SPACING, CARD_V_SPACING, CARD_ROUND, DATA_RANGE_WIDING_FACTOR, DEFAULT_X_TICK_SIZE_PX, DEFAULT_Y_TICK_SIZE_PX, X_AXIS_TICK_PADDING, Y_AXIS_TICK_PADDING, MIN_SELECTION_WIDTH, Statusmap, StatusmapRenderer; var _, $, moment, kbn, appEvents, contextSrv, d3, d3ScaleChromatic, StatusmapTooltip, AnnotationTooltip, renderComplete, CoreEvents, PanelEvents, MIN_CARD_SIZE, CARD_H_SPACING, CARD_V_SPACING, CARD_ROUND, DATA_RANGE_WIDING_FACTOR, DEFAULT_X_TICK_SIZE_PX, DEFAULT_Y_TICK_SIZE_PX, X_AXIS_TICK_PADDING, Y_AXIS_TICK_PADDING, MIN_SELECTION_WIDTH, Statusmap, StatusmapRenderer;
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
@@ -161,6 +153,8 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
_defineProperty(this, "bucketMatrix", void 0); _defineProperty(this, "bucketMatrix", void 0);
_defineProperty(this, "bucketMatrixPager", void 0);
_defineProperty(this, "panel", void 0); _defineProperty(this, "panel", void 0);
_defineProperty(this, "$heatmap", void 0); _defineProperty(this, "$heatmap", void 0);
@@ -247,9 +241,12 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
} }
if (this.panel.usingPagination) { if (this.panel.usingPagination) {
height -= this.panel.legend.show ? 140 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend ! // TODO get height of pagination controls.
// reserve height for legend and for a row of pagination controls.
height -= this.panel.legend.show ? 70 : 40; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !
} else { } else {
height -= this.panel.legend.show ? 50 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend ! // reserve height for legend
height -= this.panel.legend.show ? 32 : 4; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !
} }
this.$heatmap.css('height', height + 'px'); this.$heatmap.css('height', height + 'px');
@@ -317,10 +314,8 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
}, { }, {
key: "getYScale", key: "getYScale",
value: function getYScale(ticks) { value: function getYScale(ticks) {
var range = []; //let step = this.chartHeight / ticks.length; var range = [];
var step = this.chartHeight / ticks.length; // svg has y=0 on the top, so top card should have a minimal value in range
console.log('GETYSCALE - RENDERING', this.ctrl.getPaginationSize());
var step = this.chartHeight / this.ctrl.getPaginationSize(); // svg has y=0 on the top, so top card should have a minimal value in range
range.push(step); range.push(step);
@@ -334,10 +329,8 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
}, { }, {
key: "getYAxisScale", key: "getYAxisScale",
value: function getYAxisScale(ticks) { value: function getYAxisScale(ticks) {
var range = []; //let step = this.chartHeight / ticks.length; var range = [];
var step = this.chartHeight / ticks.length; // svg has y=0 on the top, so top tick should have a minimal value in range
console.log('GETYAXISSCALE - RENDERING', this.ctrl.getPaginationSize());
var step = this.chartHeight / this.ctrl.getPaginationSize(); // svg has y=0 on the top, so top tick should have a minimal value in range
range.push(this.yOffset); range.push(this.yOffset);
@@ -350,21 +343,7 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
}, { }, {
key: "addYAxis", key: "addYAxis",
value: function addYAxis() { value: function addYAxis() {
var ticks; var ticks = this.bucketMatrixPager.targets(); // TODO move sorting into bucketMatrixPager.
if (this.ctrl.ticksWhenPaginating !== undefined && this.ctrl.panel.usingPagination) {
ticks = _.uniq(_.map(this.ctrl.ticksWhenPaginating));
} else {
ticks = this.bucketMatrix.targets; //ticks = _.uniq(_.map(this.data, d => d.target));
} // // Set default Y min and max if no data
// if (_.isEmpty(this.data)) {
// ticks = [''];
// }
//
// // TODO
// // New version!
// let ticks = this.bucketMatrix.targets;
if (this.panel.yAxisSort == 'a → z') { if (this.panel.yAxisSort == 'a → z') {
ticks.sort(function (a, b) { ticks.sort(function (a, b) {
@@ -454,15 +433,8 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
this.yGridSize = this.chartHeight; this.yGridSize = this.chartHeight;
if (this.ctrl.panel.usingPagination) { if (this.bucketMatrixPager.targets().length > 0) {
// Pagination mode overrides count of rows. this.yGridSize = Math.floor(this.chartHeight / this.bucketMatrixPager.targets().length);
//this.yGridSize = Math.floor(this.chartHeight / this.ctrl.ticksWhenPaginating.length);
console.log('addHeatmapCanvas - rendering', this.ctrl.getPaginationSize());
this.yGridSize = Math.floor(this.chartHeight / this.ctrl.getPaginationSize());
} else {
if (this.bucketMatrix.targets.length > 0) {
this.yGridSize = Math.floor(this.chartHeight / this.bucketMatrix.targets.length);
}
} }
this.cardHeight = this.yGridSize ? this.yGridSize - this.cardVSpacing : 0; this.cardHeight = this.yGridSize ? this.yGridSize - this.cardVSpacing : 0;
@@ -499,7 +471,7 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
this.setOpacityScale(maxValue); // Draw cards from buckets. this.setOpacityScale(maxValue); // Draw cards from buckets.
this.heatmap.selectAll(".statusmap-cards-row").data(this.bucketMatrix.targets).enter().selectAll(".statustmap-card").data(function (target) { this.heatmap.selectAll(".statusmap-cards-row").data(this.bucketMatrixPager.targets()).enter().selectAll(".statustmap-card").data(function (target) {
return _this.bucketMatrix.buckets[target]; return _this.bucketMatrix.buckets[target];
}).enter().append("rect").attr("cardId", function (b) { }).enter().append("rect").attr("cardId", function (b) {
return b.id; return b.id;
@@ -878,64 +850,10 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
this.panel = this.ctrl.panel; this.panel = this.ctrl.panel;
this.timeRange = this.ctrl.range; this.timeRange = this.ctrl.range;
this.bucketMatrix = this.ctrl.bucketMatrix; this.bucketMatrix = this.ctrl.bucketMatrix;
this.bucketMatrixPager = this.ctrl.bucketMatrixPager;
if (!this.bucketMatrix || !this.setElementHeight()) { if (!this.bucketMatrix || !this.setElementHeight()) {
return; return;
} else {
// TODO pagination!
this.ctrl.cardsDataComplete = this.ctrl.bucketMatrix.buckets;
if (this.ctrl.panel.usingPagination) {
if (!this.bucketMatrix.targets) {
return;
}
this.ctrl.setFirstPageElement(this.ctrl.getCurrentPage() * this.ctrl.getPaginationSize() + 1);
var elems = this.ctrl.getTotalElements();
console.log('total elems in add heatmap canvas', elems);
if (elems < this.ctrl.getFirstPageElement()) {
this.ctrl.setCurrentPage(0);
this.render();
}
if (this.ctrl.getPaginationSize() >= this.ctrl.getTotalElements()) {
this.ctrl.setLastPageElement(this.ctrl.getTotalElements());
} else {
if (this.ctrl.getCurrentPage() + 1 === this.ctrl.getNumberOfPages() && this.ctrl.getCurrentPage() > 0) {
this.ctrl.setLastPageElement(this.ctrl.getTotalElements());
} else {
this.ctrl.setLastPageElement(this.ctrl.getCurrentPage() * this.ctrl.getPaginationSize() + this.ctrl.getPaginationSize());
}
}
var cardsList = this.ctrl.bucketMatrix.targets.slice(this.ctrl.getPaginationSize() * this.ctrl.getCurrentPage(), this.ctrl.getPaginationSize() * this.ctrl.getCurrentPage() + this.ctrl.getPaginationSize());
var cardsToShow = [];
var labelsToShow = []; // Rewrite for bucket matrix.
for (var i = 0; i < this.cardsData.cards.length; i++) {
var card = this.cardsData.cards[i];
for (var j = 0; j < cardsList.length; j++) {
var value = cardsList[j];
if (card.y === value) {
cardsToShow.push(card);
labelsToShow.push(value);
}
}
}
var labelsToShowClean = _toConsumableArray(new Set(labelsToShow));
this.cardsData.cards = cardsToShow.slice();
this.ctrl.ticksWhenPaginating = labelsToShowClean;
cardsToShow = undefined;
} else {
var pageSize = this.ctrl.bucketMatrix.targets.length;
this.ctrl.getPaginationSize(pageSize);
this.ctrl.ticksWhenPaginating = undefined;
}
} // Draw default axes and return if no data } // Draw default axes and return if no data
@@ -950,8 +868,7 @@ System.register(["lodash", "jquery", "moment", "app/core/utils/kbn", "app/core/c
this.scope.xAxisHeight = this.xAxisHeight; this.scope.xAxisHeight = this.xAxisHeight;
this.scope.chartHeight = this.chartHeight; this.scope.chartHeight = this.chartHeight;
this.scope.chartWidth = this.chartWidth; this.scope.chartWidth = this.chartWidth;
this.scope.chartTop = this.chartTop; // TODO pagination. Why this needed? this.scope.chartTop = this.chartTop;
//this.ctrl.cardsData.cards = this.ctrl.cardsDataComplete.slice();
} }
}, { }, {
key: "_renderAnnotations", key: "_renderAnnotations",
+1 -1
View File
File diff suppressed because one or more lines are too long
+145 -1
View File
@@ -3,7 +3,7 @@
System.register([], function (_export, _context) { System.register([], function (_export, _context) {
"use strict"; "use strict";
var Bucket, BucketMatrix; var Bucket, BucketMatrix, pagerChanged, BucketMatrixPager;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@@ -98,6 +98,7 @@ System.register([], function (_export, _context) {
function () { function () {
// buckets for each y label // buckets for each y label
// a flag that indicate that buckets has stub values // a flag that indicate that buckets has stub values
// An array of row labels
// TODO remove: a transition from CardsData // TODO remove: a transition from CardsData
function BucketMatrix() { function BucketMatrix() {
_classCallCheck(this, BucketMatrix); _classCallCheck(this, BucketMatrix);
@@ -155,6 +156,149 @@ System.register([], function (_export, _context) {
return BucketMatrix; return BucketMatrix;
}()); }());
_export("pagerChanged", pagerChanged = {
name: 'statusmap-pager-changed'
});
_export("BucketMatrixPager", BucketMatrixPager =
/*#__PURE__*/
function () {
function BucketMatrixPager() {
_classCallCheck(this, BucketMatrixPager);
_defineProperty(this, "bucketMatrix", void 0);
_defineProperty(this, "enable", void 0);
_defineProperty(this, "defaultPageSize", -1);
_defineProperty(this, "pageSize", -1);
_defineProperty(this, "currentPage", 0);
var m = new BucketMatrix();
this.bucketMatrix = m;
} // An array of row labels for current page.
_createClass(BucketMatrixPager, [{
key: "targets",
value: function targets() {
if (!this.enable) {
return this.bucketMatrix.targets;
}
return this.bucketMatrix.targets.slice(this.pageSize * this.currentPage, this.pageSize * (this.currentPage + 1));
}
}, {
key: "buckets",
value: function buckets() {
if (!this.enable) {
return this.bucketMatrix.buckets;
}
var buckets = {};
var me = this;
this.targets().map(function (rowLabel) {
buckets[rowLabel] = me.bucketMatrix.buckets[rowLabel];
});
return buckets;
}
}, {
key: "setEnable",
value: function setEnable(enable) {
this.enable = enable;
}
}, {
key: "setCurrent",
value: function setCurrent(num) {
this.currentPage = num;
}
}, {
key: "setDefaultPageSize",
value: function setDefaultPageSize(num) {
this.defaultPageSize = num;
}
}, {
key: "setPageSize",
value: function setPageSize(num) {
this.pageSize = num;
}
}, {
key: "pages",
value: function pages() {
return Math.ceil(this.totalRows() / this.pageSize);
}
}, {
key: "totalRows",
value: function totalRows() {
return this.bucketMatrix.targets.length;
}
}, {
key: "pageStartRow",
value: function pageStartRow() {
if (!this.enable) {
return 1;
}
return this.pageSize * this.currentPage + 1;
}
}, {
key: "pageEndRow",
value: function pageEndRow() {
if (!this.enable) {
return this.totalRows();
}
var last = this.pageSize * (this.currentPage + 1);
if (last > this.totalRows()) {
return this.totalRows();
}
return last;
}
}, {
key: "hasNext",
value: function hasNext() {
if (!this.enable) {
return false;
}
if ((this.currentPage + 1) * this.pageSize >= this.totalRows()) {
return false;
}
return true; // currentPage >= ctrl.bucketMatrix.targets.length/ctrl.pageSizeViewer - 1 || ctrl.numberOfPages == 0
}
}, {
key: "hasPrev",
value: function hasPrev() {
if (!this.enable) {
return false;
}
return this.currentPage > 0;
}
}, {
key: "switchToNext",
value: function switchToNext() {
if (this.hasNext()) {
this.currentPage = this.currentPage + 1;
}
}
}, {
key: "switchToPrev",
value: function switchToPrev() {
if (this.hasPrev()) {
this.currentPage = this.currentPage - 1;
}
}
}]);
return BucketMatrixPager;
}());
} }
}; };
}); });
+1 -1
View File
File diff suppressed because one or more lines are too long
-248
View File
@@ -1,248 +0,0 @@
"use strict";
System.register(["d3", "lodash", "jquery", "./extra_series_format"], function (_export, _context) {
"use strict";
var d3, _, $, ExtraSeriesFormatValue, TOOLTIP_PADDING_X, TOOLTIP_PADDING_Y, StatusHeatmapTooltipExtraSeries;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
return {
setters: [function (_d) {
d3 = _d.default;
}, function (_lodash) {
_ = _lodash.default;
}, function (_jquery) {
$ = _jquery.default;
}, function (_extra_series_format) {
ExtraSeriesFormatValue = _extra_series_format.ExtraSeriesFormatValue;
}],
execute: function () {
TOOLTIP_PADDING_X = -50;
TOOLTIP_PADDING_Y = 5;
_export("StatusHeatmapTooltipExtraSeries", StatusHeatmapTooltipExtraSeries =
/*#__PURE__*/
function () {
function StatusHeatmapTooltipExtraSeries(elem, scope) {
_classCallCheck(this, StatusHeatmapTooltipExtraSeries);
_defineProperty(this, "scope", void 0);
_defineProperty(this, "dashboard", void 0);
_defineProperty(this, "panelCtrl", void 0);
_defineProperty(this, "panel", void 0);
_defineProperty(this, "heatmapPanel", void 0);
_defineProperty(this, "mouseOverBucket", void 0);
_defineProperty(this, "originalFillColor", void 0);
_defineProperty(this, "tooltip", void 0);
this.scope = scope;
this.dashboard = scope.ctrl.dashboard;
this.panelCtrl = scope.ctrl;
this.panel = scope.ctrl.panel;
this.heatmapPanel = elem;
this.mouseOverBucket = false;
this.originalFillColor = null;
elem.on("mouseover", this.onMouseOver.bind(this));
elem.on("click", this.onMouseClick.bind(this));
}
_createClass(StatusHeatmapTooltipExtraSeries, [{
key: "onMouseOver",
value: function onMouseOver(e) {
if (!this.panel.usingUrl || !this.scope.ctrl.data || _.isEmpty(this.scope.ctrl.data)) {
return;
}
}
}, {
key: "onMouseClick",
value: function onMouseClick(e) {
if (!this.panel.usingUrl) {
return;
}
this.destroy();
this.add();
}
}, {
key: "add",
value: function add() {
this.tooltip = d3.select("body").append("div").attr("class", "statusmap-tooltip-extraseries graph-tooltip grafana-tooltip");
}
}, {
key: "destroy",
value: function destroy() {
if (this.tooltip) {
this.tooltip.remove();
}
this.tooltip = null;
}
}, {
key: "show",
value: function show(pos) {
if (!this.panel.usingUrl || !this.tooltip) {
return;
} // shared tooltip mode
if (pos.panelRelY) {
return;
}
var cardId = d3.select(pos.target).attr('cardId');
if (!cardId) {
this.destroy();
return;
}
var card;
if (this.panel.usingPagination) {
card = this.panelCtrl.cardsDataComplete[cardId];
} else {
card = this.panelCtrl.cardsData.cards[cardId];
}
if (!card) {
this.destroy();
return;
}
if (card.value == null) {
this.destroy();
return;
}
var x = card.x;
var y = card.y;
var value = card.value;
var values = card.values;
var tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';
var time = this.dashboard.formatDate(+x, tooltipTimeFormat);
var tooltipHtml = "<div class=\"graph-tooltip-time\">".concat(time, "</div>");
if (this.panel.color.mode === 'discrete') {
var statuses = "";
if (this.panelCtrl.panel.seriesFilterIndex == -1) {
statuses = this.panelCtrl.discreteExtraSeries.convertValuesToTooltips(values);
} else {
statuses = this.panelCtrl.discreteExtraSeries.convertValueToTooltips(value);
}
tooltipHtml += "\n <div>\n name: <b>".concat(y, "</b>\n <div>\n <br>\n <span>status:</span>\n <ul>\n ").concat(_.join(_.map(statuses, function (v) {
return "<p style=\"background-color: ".concat(v.color, "; text-align:center\" class=\"discrete-item\">").concat(v.tooltip, "</p>");
}), ""), "\n </ul>\n </div> \n </div> <br>");
}
tooltipHtml += "<div class=\"statusmap-histogram\"></div>";
var urls = this.panelCtrl.panel.urls;
var rtime = this.panelCtrl.retrieveTimeVar();
var curl = JSON.parse(JSON.stringify(urls));
for (var i = 0; i < curl.length; i++) {
//Change name var
curl[i].base_url = _.replace(curl[i].base_url, /\$series_label/g, y); //Set up extra series
if (curl[i].useExtraSeries == true) {
var tf = curl[i].extraSeries.format;
var vh = card.values[curl[i].extraSeries.index]; //let extraSeries: any = this.dashboard.formatDate(+vh, tf)
var series_extra = this.formatExtraSeries(vh, tf);
curl[i].base_url = _.replace(curl[i].base_url, /\$series_extra/g, series_extra);
} //Change time var
curl[i].base_url = _.replace(curl[i].base_url, /\$time/g, rtime); //Replace vars
curl[i].base_url = this.panelCtrl.renderLink(curl[i].base_url, this.panelCtrl.variableSrv.variables);
}
if (this.panelCtrl.panel.usingUrl == true) {
tooltipHtml += "\n <div bs-tooltip='Settings' data-placement=\"right\">\n ".concat(_.join(_.map(curl, function (v) {
return "<div ><a href=\"".concat(v.forcelowercase ? v.base_url.toLowerCase() : v.base_url, "\" target=\"_blank\"><div class=\"dashlist-item\">\n <p class=\"dashlist-link dashlist-link-dash-db\"><span style=\"word-wrap: break-word;\" class=\"dash-title\">").concat(v.label ? v.label : v.base_url != "" ? _.truncate(v.base_url) : "Empty URL", "</span><span class=\"dashlist-star\">\n <i class=\"fa fa-").concat(v.icon_fa, "\"></i>\n </span></p> </div></a><div>");
}), ""), "\n </div> <br>");
} // "Ambiguous bucket state: Multiple values!";
if (!this.panel.useMax && card.multipleValues) {
tooltipHtml += "<div><b>Error:</b> ".concat(this.panelCtrl.dataWarnings.multipleValues.title, "</div>");
} // Discrete mode errors
if (this.panel.color.mode === 'discrete') {
if (card.noColorDefined) {
var badValues = this.panelCtrl.discreteExtraSeries.getNotColoredValues(values);
tooltipHtml += "<div><b>Error:</b> ".concat(this.panelCtrl.dataWarnings.noColorDefined.title, "\n <br>not colored values:\n <ul>\n ").concat(_.join(_.map(badValues, function (v) {
return "<li>".concat(v, "</li>");
}), ""), "\n </ul>\n </div>");
}
}
this.tooltip.html(tooltipHtml);
this.move(pos);
}
}, {
key: "formatExtraSeries",
value: function formatExtraSeries(value, type) {
var extraSeries = '';
switch (type) {
case ExtraSeriesFormatValue.Date:
extraSeries = this.dashboard.formatDate(+value, type);
return extraSeries;
case ExtraSeriesFormatValue.Raw:
extraSeries = value;
return extraSeries;
default:
return extraSeries;
}
}
}, {
key: "move",
value: function move(pos) {
if (!this.tooltip) {
return;
}
var elem = $(this.tooltip.node())[0];
var tooltipWidth = elem.clientWidth;
var tooltipHeight = elem.clientHeight;
var left = pos.pageX + TOOLTIP_PADDING_X;
var top = pos.pageY + TOOLTIP_PADDING_Y;
if (pos.pageX + tooltipWidth + 40 > window.innerWidth) {
left = pos.pageX - tooltipWidth - TOOLTIP_PADDING_X;
}
if (pos.pageY - window.pageYOffset + tooltipHeight + 20 > window.innerHeight) {
top = pos.pageY - tooltipHeight - TOOLTIP_PADDING_Y;
}
return this.tooltip.style("left", left + "px").style("top", top + "px");
}
}]);
return StatusHeatmapTooltipExtraSeries;
}());
}
};
});
//# sourceMappingURL=tooltipextraseries.js.map
File diff suppressed because one or more lines are too long
+14
View File
@@ -102,6 +102,20 @@
width: 70.0rem!important width: 70.0rem!important
} }
.statusmap-pagination {
// space between legend and pagination controls
margin-top: 5px;
label {
margin-right:0px;
}
input {
margin-right: 0px;
}
.last-in-group {
margin-right: 4px;
}
}
.pagination-buttons{text-align: right;} .pagination-buttons{text-align: right;}
.status-heatmap-legend-wrapper { .status-heatmap-legend-wrapper {
-9
View File
@@ -1,9 +0,0 @@
export enum ExtraSeriesFormat {
Date = 'Date',
Raw = 'Raw',
}
export enum ExtraSeriesFormatValue {
Date = 'YYYY/MM/DD/HH_mm_ss',
Raw = '',
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+24 -24
View File
@@ -1,37 +1,37 @@
<div class="status-heatmap-wrapper"> <div class="status-heatmap-wrapper">
<div class="clearfix"></div>
<br>
<div class="gf-form" ng-if="ctrl.panel.usingPagination">
<label class="gf-form-label width-9">Items per page</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right"
bs-tooltip="'Number of items to show per page.'" ng-model="ctrl.pageSizeViewer" ng-change="ctrl.changePaginationSize()"
ng-model-onblur>
</div>
<div class="status-heatmap-canvas-wrapper"> <div class="status-heatmap-canvas-wrapper">
<div class="datapoints-warning" ng-if="ctrl.multipleValues || ctrl.noColorDefined || ctrl.noDatapoints"> <div class="datapoints-warning" ng-if="ctrl.multipleValues || ctrl.noColorDefined || ctrl.noDatapoints">
<span class="small" ng-if="ctrl.multipleValues" bs-tooltip="'{{ctrl.dataWarnings.multipleValues.tip}}'">{{ctrl.dataWarnings.multipleValues.title}}</span> <span class="small" ng-if="ctrl.multipleValues" bs-tooltip="'{{ctrl.dataWarnings.multipleValues.tip}}'">{{ctrl.dataWarnings.multipleValues.title}}</span>
<span class="small" ng-if="ctrl.noColorDefined" bs-tooltip="'{{ctrl.dataWarnings.noColorDefined.tip}}'">{{ctrl.dataWarnings.noColorDefined.title}}</span> <span class="small" ng-if="ctrl.noColorDefined" bs-tooltip="'{{ctrl.dataWarnings.noColorDefined.tip}}'">{{ctrl.dataWarnings.noColorDefined.title}}</span>
<span class="small" ng-if="ctrl.noDatapoints" bs-tooltip="'{{ctrl.dataWarnings.noDatapoints.tip}}'">{{ctrl.dataWarnings.noDatapoints.title}}</span> <span class="small" ng-if="ctrl.noDatapoints" bs-tooltip="'{{ctrl.dataWarnings.noDatapoints.tip}}'">{{ctrl.dataWarnings.noDatapoints.title}}</span>
</div> </div>
<div class="statusmap-panel" ng-dblclick="ctrl.zoomOut()"></div>
</div>
<div class="status-heatmap-panel" ng-dblclick="ctrl.zoomOut()"></div>
</div>
<div class="pagination" ng-if="ctrl.panel.usingPagination">
Showing {{ctrl.firstPageElement}} to {{ctrl.lastPageElement}} of {{ctrl.totalElements}} entries
<div class="pagination-buttons">
<button class="btn btn-inverse" ng-disabled="ctrl.currentPage == 0" ng-click="ctrl.currentPage=ctrl.currentPage-1; ctrl.render()">
Previous
</button>
{{ctrl.currentPage+1}}/{{ctrl.numberOfPages}}
<button class="btn btn-inverse" ng-disabled="ctrl.currentPage >= ctrl.cardsData.targets.length/ctrl.pageSizeViewer - 1 || ctrl.numberOfPages == 0" ng-click="ctrl.currentPage=ctrl.currentPage+1; ctrl.render()">
Next
</button>
</div>
</div>
<div class="status-heatmap-legend-wrapper" ng-if="ctrl.panel.legend.show"> <div class="status-heatmap-legend-wrapper" ng-if="ctrl.panel.legend.show">
<status-heatmap-legend></status-heatmap-legend> <status-heatmap-legend></status-heatmap-legend>
</div> </div>
<div class="clearfix"></div>
<div class="statusmap-pagination gf-form" ng-if="ctrl.panel.usingPagination">
<div class="gf-form">
<button class="btn btn-inverse" ng-disabled="!pager.hasPrev()" ng-click="ctrl.onPrevPage()">
<i class="fa fa-arrow-left"></i>&nbsp;Previous
</button>
<label class="gf-form-label">{{pager.currentPage+1}}/{{pager.pages()}}</label>
<button class="btn btn-inverse last-in-group" ng-disabled="!pager.hasNext()" ng-click="ctrl.onNextPage()">
Next&nbsp;<i class="fa fa-arrow-right"></i>
</button>
</div>
<div class="gf-form">
<label class="gf-form-label">Rows per page</label>
<input type="number" class="gf-form-input width-3 last-in-group" placeholder="12" data-placement="top"
bs-tooltip="'Number of rows to show per page.'" ng-model="ctrl.pageSizeViewer" ng-change="ctrl.onChangePageSize()"
ng-model-onblur>
</div>
<label class="gf-form-label">Show {{pager.pageStartRow()}} to {{pager.pageEndRow()}} of {{pager.totalRows()}} rows</label>
</div>
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
+35 -72
View File
@@ -16,7 +16,7 @@ import {loadPluginCss} from 'app/plugins/sdk';
import { MetricsPanelCtrl } from 'app/plugins/sdk'; import { MetricsPanelCtrl } from 'app/plugins/sdk';
import { AnnotationsSrv } from 'app/features/annotations/annotations_srv'; import { AnnotationsSrv } from 'app/features/annotations/annotations_srv';
import { CoreEvents, PanelEvents } from './libs/grafana/events/index'; import { CoreEvents, PanelEvents } from './libs/grafana/events/index';
import { Bucket, BucketMatrix } from './statusmap_data'; import {Bucket, BucketMatrix, BucketMatrixPager } from './statusmap_data';
import rendering from './rendering'; import rendering from './rendering';
import { Polygrafill } from './libs/polygrafill/index'; import { Polygrafill } from './libs/polygrafill/index';
@@ -70,6 +70,7 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
data: any; data: any;
bucketMatrix: BucketMatrix; bucketMatrix: BucketMatrix;
bucketMatrixPager: BucketMatrixPager;
graph: any; graph: any;
discreteHelper: ColorModeDiscrete; discreteHelper: ColorModeDiscrete;
@@ -78,10 +79,6 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
colorSchemes: any = []; colorSchemes: any = [];
unitFormats: any; unitFormats: any;
cardsDataComplete: any;
cardsDataLabelsComplete: any;
ticksWhenPaginating: [];
dataWarnings: {[warningId: string]: {title: string, tip: string}} = {}; dataWarnings: {[warningId: string]: {title: string, tip: string}} = {};
multipleValues: boolean; multipleValues: boolean;
noColorDefined: boolean; noColorDefined: boolean;
@@ -92,12 +89,8 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
annotations: object[] = []; annotations: object[] = [];
annotationsPromise: any; annotationsPromise: any;
// TODO remove this transient variable: use ng-model-options="{ getterSetter: true }"
pageSizeViewer: number = 15; pageSizeViewer: number = 15;
currentPage: number = 0;
numberOfPages: number = 1;
totalElements: number = 0;
firstPageElement: number = 1;
lastPageElement: number = 5;
panelDefaults: any = { panelDefaults: any = {
// datasource name, null = default datasource // datasource name, null = default datasource
@@ -144,10 +137,10 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
useMax: true, useMax: true,
seriesFilterIndex: -1, seriesFilterIndex: -1,
// Pagination options
usingPagination: false, usingPagination: false,
pageSize: 15, pageSize: 15
allowAllElements: false,
availableValues: []
}; };
/** @ngInject */ /** @ngInject */
@@ -163,10 +156,14 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
migratePanelConfig(this.panel); migratePanelConfig(this.panel);
_.defaultsDeep(this.panel, this.panelDefaults); _.defaultsDeep(this.panel, this.panelDefaults);
if (this.panel.usingPagination) { this.bucketMatrix = new BucketMatrix();
this.setPaginationSize(this.panel.pageSize);
this.setCurrentPage(0); // Create pager for bucketMatrix and restore page size.
} this.bucketMatrixPager = new BucketMatrixPager();
this.bucketMatrixPager.setEnable(this.panel.usingPagination);
this.bucketMatrixPager.setDefaultPageSize(this.panel.pageSize);
this.bucketMatrixPager.setPageSize(this.panel.pageSize);
$scope.pager = this.bucketMatrixPager;
this.opacityScales = opacityScales; this.opacityScales = opacityScales;
this.colorModes = colorModes; this.colorModes = colorModes;
@@ -220,66 +217,35 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
} }
changeDefaultPaginationSize(defaultPageSize: number): void { changeDefaultPaginationSize(defaultPageSize: number): void {
this.bucketMatrixPager.setDefaultPageSize(defaultPageSize);
this.bucketMatrixPager.setPageSize(defaultPageSize);
this.pageSizeViewer = defaultPageSize; this.pageSizeViewer = defaultPageSize;
this.render(); this.render();
this.refresh(); this.refresh();
} }
changePaginationSize(): void { onChangePageSize(): void {
if (this.pageSizeViewer <= 0) { if (this.pageSizeViewer <= 0) {
this.pageSizeViewer = 1; this.pageSizeViewer = this.bucketMatrixPager.defaultPageSize;
} }
this.bucketMatrixPager.setPageSize(this.pageSizeViewer);
this.currentPage = 0; this.bucketMatrixPager.setCurrent(0);
this.render(); this.render();
this.refresh(); this.refresh();
} }
getPaginationSize(): number { onPrevPage(): void {
return this.pageSizeViewer; this.bucketMatrixPager.switchToPrev();
this.render();
} }
setPaginationSize(pageSize: number): void { onNextPage(): void {
this.pageSizeViewer = pageSize; this.bucketMatrixPager.switchToNext();
this.render();
} }
getCurrentPage(): number {
return this.currentPage;
}
setCurrentPage(currentPage: number): void {
this.currentPage = currentPage;
}
getNumberOfPages(): number {
return this.numberOfPages;
}
getTotalElements(): number {
return this.totalElements;
}
setTotalElements(totalElements: number): void {
this.totalElements = totalElements;
}
getFirstPageElement(): number {
return this.firstPageElement;
}
setFirstPageElement(firstPageElement: number): void {
this.firstPageElement = firstPageElement;
}
getLastPageElement(): number {
return this.lastPageElement;
}
setLastPageElement(lastPageElement: number): void {
this.lastPageElement = lastPageElement;
}
// getChartWidth returns an approximation of chart canvas width or // getChartWidth returns an approximation of chart canvas width or
// a saved value calculated during a render. // a saved value calculated during a render.
@@ -402,16 +368,17 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
if (!this.intervalMs) { if (!this.intervalMs) {
this.calculateInterval(); this.calculateInterval();
} }
this.bucketMatrix = this.convertDataToBuckets(dataList, this.range.from.valueOf(), this.range.to.valueOf(), this.intervalMs, true);
this.noDatapoints = this.bucketMatrix.noDatapoints;
if (this.panel.usingPagination && this.cardsData.targets) { let newBucketMatrix = this.convertDataToBuckets(dataList, this.range.from.valueOf(), this.range.to.valueOf(), this.intervalMs, true);
this.numberOfPages = Math.ceil(this.cardsData.targets.length/this.pageSizeViewer);
this.totalElements = this.cardsData.targets.length; this.bucketMatrix = newBucketMatrix;
} else { this.bucketMatrixPager.bucketMatrix = newBucketMatrix;
this.setPaginationSize(this.cardsData.targets.length); if (newBucketMatrix.targets.length !== this.bucketMatrix.targets.length) {
this.bucketMatrixPager.setCurrent(0);
} }
this.noDatapoints = this.bucketMatrix.noDatapoints;
if (this.annotationsPromise) { if (this.annotationsPromise) {
this.annotationsPromise.then( this.annotationsPromise.then(
(result: { alertState: any; annotations: any }) => { (result: { alertState: any; annotations: any }) => {
@@ -427,7 +394,7 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
() => { () => {
this.loading = false; this.loading = false;
this.annotations = []; this.annotations = [];
this.render(); // this.render(this.data);??? this.render();
} }
); );
} else { } else {
@@ -443,10 +410,6 @@ class StatusHeatmapCtrl extends MetricsPanelCtrl {
this.unitFormats = kbn.getUnitFormats(); this.unitFormats = kbn.getUnitFormats();
} }
paginate() {
this.refresh();
}
// onRender will be called before StatusmapRenderer.onRender. // onRender will be called before StatusmapRenderer.onRender.
// Decide if warning should be displayed over cards. // Decide if warning should be displayed over cards.
onRender() { onRender() {
+6 -107
View File
@@ -216,119 +216,18 @@
</div> </div>
</div> </div>
<div class="section gf-form-group width-30">
<h5 class="section-heading">Filtering</h5>
<div class="gf-form">
<label class="gf-form-label width-9">Show only serie with Index</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right"
bs-tooltip="'Filter with the serie index to show the value on graph. Use -1 to get all values'" ng-model="ctrl.panel.seriesFilterIndex" ng-change="ctrl.refresh()"
ng-model-onblur>
</div>
</div>
<div class="section gf-form-group"> <div class="section gf-form-group">
<h5 class="section-heading">Pagination options</h5> <h5 class="section-heading">Pagination</h5>
<div class="gf-form"> <div class="gf-form">
<gf-form-switch class="gf-form" label="Paginate elements" label-class="width-12" <gf-form-switch class="gf-form" label="Enable pagination" label-class="width-12"
checked="ctrl.panel.usingPagination" on-change="ctrl.paginate()"></gf-form-switch> checked="ctrl.panel.usingPagination" on-change="ctrl.render()"></gf-form-switch>
</div> </div>
<div class="gf-form" ng-if="ctrl.panel.usingPagination"> <div class="gf-form" ng-if="ctrl.panel.usingPagination">
<label class="gf-form-label width-9">Items per Page by default</label> <label class="gf-form-label width-10">Rows per page</label>
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right" <input type="number" class="gf-form-input width-5" placeholder="2" data-placement="top"
bs-tooltip="Number of items to show by default" ng-model="ctrl.panel.pageSize" ng-change="ctrl.changeDefaultPaginationSize(ctrl.panel.pageSize)" bs-tooltip="'Number of rows to show by default'" ng-model="ctrl.panel.pageSize" ng-change="ctrl.changeDefaultPaginationSize(ctrl.panel.pageSize)"
ng-model-onblur> ng-model-onblur>
</div> </div>
</div> </div>
<div class="section gf-form-group">
<h5 class="section-heading">URL</h5>
<div class="gf-form">
Insert the url to navigate<br />
</div>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Show extraSeries Tooltip when clicking elements" label-class="width-12"
checked="ctrl.panel.usingUrl" on-change="ctrl.render()"></gf-form-switch>
</div>
<div class="section gf-form-group" ng-if="ctrl.panel.usingUrl">
<br>
<div class="gf-form-inline">
<div class="gf-form"></div>
<div class="gf-form">
<button class="btn btn-inverse" ng-click="ctrl.onEditorAddUrl()">
<i class="fa fa-plus"></i> Add new URL
</button>
</div>
<div class="gf-form">
<button class="btn btn-inverse" ng-click="ctrl.onEditorRemoveUrls()">
<i class="fa fa-minus"></i> Remove all URLs
</button>
</div>
</div>
<div class="gf-form-block" ng-repeat="url in ctrl.panel.urls">
<div class="gf-form">
<label class="gf-form-label width-2">{{ $index }}</label>
<label class="gf-form-label width-2">
<a class="pointer" tabindex="1" ng-click="ctrl.onEditorRemoveUrl($index)">
<i class="fa fa-trash" />
</a>
</label>
<label class="gf-form-label width-4">Label: </label>
<input type="text" class="gf-form-input width-16" placeholder="My URL" data-placement="right"
ng-model="url.label" ng-change="ctrl.refresh()">
<label class="gf-form-label width-4">URL: </label>
<input type="text" class="gf-form-input width-c-50" placeholder="https://www.google.es" data-placement="right"
bs-tooltip="'This is the url to be shown when the user clicks on it'" ng-model="url.base_url"
ng-change="ctrl.refresh()">
<info-popover mode="right-normal">
<p>Specify an URL (relative or absolute)</p>
<span>
Use special variables to specify cell values:
<br>
<em>$series_label</em> name of the serie
<br>
<em>$(template.name)</em> name of the templated to be replaced
<br>
<em>$time</em> append &from...&to on the URL
<br>
<em>$series_extra</em> use extraSeries value to use it on URL
</span>
</info-popover>
</div>
<div class="gf-form">
<label class="gf-form-label width-4">Icon: </label>
<input type="text" class="gf-form-input width-12" placeholder="FA Icon" data-placement="right"
bs-tooltip="'The icon shown on URL'" ng-model="url.icon_fa" ng-change="ctrl.refresh()">
<gf-form-switch class="gf-form" label-class="width-8" label="Force lowercase" checked="url.forcelowercase"
on-change="ctrl.render()">
</gf-form-switch>
<gf-form-switch class="gf-form" label-class="width-6" label="Use Extra Serie Data" checked="url.useExtraSeries"
on-change="ctrl.render()">
</gf-form-switch>
<div class="gf-form" ng-if="url.useExtraSeries == true">
<label class="gf-form-label width-8">Extra Series Index: </label>
<input type="number" class="gf-form-input width-12" placeholder="0" ng-if="url.useExtraSeries == true"
data-placement="right" bs-tooltip="'Fields index to use its value on URL using $series_extra. Use -1 to disable it'" ng-model="url.extraSeries.index"
ng-change="ctrl.refresh()">
<label class="gf-form-label width-9">Type</label>
<div class="gf-form-select-wrapper width-8">
<select class="input-small gf-form-input" ng-model="url.type" ng-options="s for s in ctrl.extraSeriesFormats" ng-change="ctrl.onChangeType(url)"></select>
</div>
<div ng-if="url.type === 'Date'">
<label class="gf-form-label width-12">Extra Series Date Format: </label>
<input type="text" class="gf-form-input width-12" placeholder="YYYY/MM/DD/HH_mm_ss" ng-if="url.useExtraSeries == true"
data-placement="right" bs-tooltip="'Date format to transformat extraSeries'" ng-model="url.extraSeries.format"
ng-change="ctrl.refresh()">
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
+15 -104
View File
@@ -7,7 +7,7 @@ import * as d3 from 'd3';
import * as d3ScaleChromatic from './libs/d3-scale-chromatic/index'; import * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';
import {StatusmapTooltip} from './tooltip'; import {StatusmapTooltip} from './tooltip';
import {AnnotationTooltip} from './annotations'; import {AnnotationTooltip} from './annotations';
import { Bucket, BucketMatrix } from './statusmap_data'; import { Bucket, BucketMatrix, BucketMatrixPager } from './statusmap_data';
import { StatusHeatmapCtrl, renderComplete } from './module'; import { StatusHeatmapCtrl, renderComplete } from './module';
import { CoreEvents, PanelEvents } from './libs/grafana/events/index'; import { CoreEvents, PanelEvents } from './libs/grafana/events/index';
@@ -61,6 +61,7 @@ export class StatusmapRenderer {
yGridSize: number = 0; yGridSize: number = 0;
bucketMatrix: BucketMatrix; bucketMatrix: BucketMatrix;
bucketMatrixPager: BucketMatrixPager;
panel: any; panel: any;
$heatmap: any; $heatmap: any;
tooltip: StatusmapTooltip; tooltip: StatusmapTooltip;
@@ -134,9 +135,12 @@ export class StatusmapRenderer {
} }
if (this.panel.usingPagination) { if (this.panel.usingPagination) {
height -= this.panel.legend.show ? 140 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend ! // TODO get height of pagination controls.
// reserve height for legend and for a row of pagination controls.
height -= this.panel.legend.show ? 70 : 40; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !
} else { } else {
height -= this.panel.legend.show ? 50 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend ! // reserve height for legend
height -= this.panel.legend.show ? 32 : 4; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !
} }
this.$heatmap.css('height', height + 'px'); this.$heatmap.css('height', height + 'px');
@@ -214,9 +218,7 @@ export class StatusmapRenderer {
// divide chart height by ticks for cards drawing // divide chart height by ticks for cards drawing
getYScale(ticks: any[]) { getYScale(ticks: any[]) {
let range:any[] = []; let range:any[] = [];
//let step = this.chartHeight / ticks.length; let step = this.chartHeight / ticks.length;
console.log('GETYSCALE - RENDERING', this.ctrl.getPaginationSize());
let step = this.chartHeight / this.ctrl.getPaginationSize();
// svg has y=0 on the top, so top card should have a minimal value in range // svg has y=0 on the top, so top card should have a minimal value in range
range.push(step); range.push(step);
for (let i = 1; i < ticks.length; i++) { for (let i = 1; i < ticks.length; i++) {
@@ -230,9 +232,7 @@ export class StatusmapRenderer {
// divide chart height by ticks with offset for ticks drawing // divide chart height by ticks with offset for ticks drawing
getYAxisScale(ticks: any[]) { getYAxisScale(ticks: any[]) {
let range:any[] = []; let range:any[] = [];
//let step = this.chartHeight / ticks.length; let step = this.chartHeight / ticks.length;
console.log('GETYAXISSCALE - RENDERING', this.ctrl.getPaginationSize());
let step = this.chartHeight / this.ctrl.getPaginationSize();
// svg has y=0 on the top, so top tick should have a minimal value in range // svg has y=0 on the top, so top tick should have a minimal value in range
range.push(this.yOffset); range.push(this.yOffset);
for (let i = 1; i < ticks.length; i++) { for (let i = 1; i < ticks.length; i++) {
@@ -244,26 +244,9 @@ export class StatusmapRenderer {
} }
addYAxis() { addYAxis() {
let ticks = this.bucketMatrixPager.targets();
let ticks; // TODO move sorting into bucketMatrixPager.
if(this.ctrl.ticksWhenPaginating !== undefined && this.ctrl.panel.usingPagination) {
ticks = _.uniq(_.map(this.ctrl.ticksWhenPaginating));
} else {
ticks = this.bucketMatrix.targets;
//ticks = _.uniq(_.map(this.data, d => d.target));
}
// // Set default Y min and max if no data
// if (_.isEmpty(this.data)) {
// ticks = [''];
// }
//
// // TODO
// // New version!
// let ticks = this.bucketMatrix.targets;
if (this.panel.yAxisSort == 'a → z') { if (this.panel.yAxisSort == 'a → z') {
ticks.sort((a, b) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true})); ticks.sort((a, b) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true}));
} else if (this.panel.yAxisSort == 'z → a') { } else if (this.panel.yAxisSort == 'z → a') {
@@ -352,17 +335,9 @@ export class StatusmapRenderer {
// calculate yOffset for YAxis // calculate yOffset for YAxis
this.yGridSize = this.chartHeight; this.yGridSize = this.chartHeight;
if (this.ctrl.panel.usingPagination) { if (this.bucketMatrixPager.targets().length > 0) {
// Pagination mode overrides count of rows. this.yGridSize = Math.floor(this.chartHeight / this.bucketMatrixPager.targets().length);
//this.yGridSize = Math.floor(this.chartHeight / this.ctrl.ticksWhenPaginating.length);
console.log('addHeatmapCanvas - rendering',this.ctrl.getPaginationSize());
this.yGridSize = Math.floor(this.chartHeight / this.ctrl.getPaginationSize());
} else {
if (this.bucketMatrix.targets.length > 0) {
this.yGridSize = Math.floor(this.chartHeight / this.bucketMatrix.targets.length);
}
} }
this.cardHeight = this.yGridSize ? this.yGridSize - this.cardVSpacing : 0; this.cardHeight = this.yGridSize ? this.yGridSize - this.cardVSpacing : 0;
this.yOffset = this.cardHeight / 2; this.yOffset = this.cardHeight / 2;
@@ -398,7 +373,7 @@ export class StatusmapRenderer {
this.setOpacityScale(maxValue); this.setOpacityScale(maxValue);
// Draw cards from buckets. // Draw cards from buckets.
this.heatmap.selectAll(".statusmap-cards-row").data(this.bucketMatrix.targets) this.heatmap.selectAll(".statusmap-cards-row").data(this.bucketMatrixPager.targets())
.enter() .enter()
.selectAll(".statustmap-card") .selectAll(".statustmap-card")
.data((target:string) => this.bucketMatrix.buckets[target]) .data((target:string) => this.bucketMatrix.buckets[target])
@@ -778,75 +753,14 @@ export class StatusmapRenderer {
} }
} }
render() { render() {
this.panel = this.ctrl.panel; this.panel = this.ctrl.panel;
this.timeRange = this.ctrl.range; this.timeRange = this.ctrl.range;
this.bucketMatrix = this.ctrl.bucketMatrix; this.bucketMatrix = this.ctrl.bucketMatrix;
this.bucketMatrixPager = this.ctrl.bucketMatrixPager;
if (!this.bucketMatrix || !this.setElementHeight()) { if (!this.bucketMatrix || !this.setElementHeight()) {
return; return;
} else {
// TODO pagination!
this.ctrl.cardsDataComplete = this.ctrl.bucketMatrix.buckets;
if(this.ctrl.panel.usingPagination) {
if (!this.bucketMatrix.targets) {
return;
}
this.ctrl.setFirstPageElement((this.ctrl.getCurrentPage()*this.ctrl.getPaginationSize())+1);
let elems = this.ctrl.getTotalElements();
console.log('total elems in add heatmap canvas', elems);
if (elems < this.ctrl.getFirstPageElement()) {
this.ctrl.setCurrentPage(0);
this.render();
}
if (this.ctrl.getPaginationSize() >= this.ctrl.getTotalElements()) {
this.ctrl.setLastPageElement(this.ctrl.getTotalElements());
} else {
if ((this.ctrl.getCurrentPage()+1) === this.ctrl.getNumberOfPages() && (this.ctrl.getCurrentPage()>0)) {
this.ctrl.setLastPageElement(this.ctrl.getTotalElements());
} else {
this.ctrl.setLastPageElement((this.ctrl.getCurrentPage() * this.ctrl.getPaginationSize())+this.ctrl.getPaginationSize());
}
}
let cardsList = this.ctrl.bucketMatrix.targets.slice(this.ctrl.getPaginationSize()*this.ctrl.getCurrentPage(),
(this.ctrl.getPaginationSize()*this.ctrl.getCurrentPage())+this.ctrl.getPaginationSize());
let cardsToShow = [];
let labelsToShow = [];
// Rewrite for bucket matrix.
for (let i = 0; i < this.cardsData.cards.length; i++) {
const card = this.cardsData.cards[i];
for (let j = 0; j < cardsList.length; j++) {
const value = cardsList[j];
if (card.y === value) {
cardsToShow.push(card);
labelsToShow.push(value);
}
}
}
const labelsToShowClean = [...new Set(labelsToShow)];
this.cardsData.cards = cardsToShow.slice();
this.ctrl.ticksWhenPaginating = labelsToShowClean;
cardsToShow = undefined;
} else {
const pageSize = this.ctrl.bucketMatrix.targets.length
this.ctrl.getPaginationSize(pageSize);
this.ctrl.ticksWhenPaginating = undefined;
}
} }
// Draw default axes and return if no data // Draw default axes and return if no data
@@ -861,9 +775,6 @@ export class StatusmapRenderer {
this.scope.chartHeight = this.chartHeight; this.scope.chartHeight = this.chartHeight;
this.scope.chartWidth = this.chartWidth; this.scope.chartWidth = this.chartWidth;
this.scope.chartTop = this.chartTop; this.scope.chartTop = this.chartTop;
// TODO pagination. Why this needed?
//this.ctrl.cardsData.cards = this.ctrl.cardsDataComplete.slice();
} }
_renderAnnotations() { _renderAnnotations() {
+120 -1
View File
@@ -62,6 +62,7 @@ class BucketMatrix {
// a flag that indicate that buckets has stub values // a flag that indicate that buckets has stub values
noDatapoints: boolean = false; noDatapoints: boolean = false;
// An array of row labels
targets: string[] = []; targets: string[] = [];
rangeMs: number = 0; rangeMs: number = 0;
intervalMs: number = 0; intervalMs: number = 0;
@@ -93,4 +94,122 @@ class BucketMatrix {
} }
} }
export {Bucket, BucketMatrix }; export var pagerChanged:any = {name:'statusmap-pager-changed'};
class BucketMatrixPager {
bucketMatrix: BucketMatrix;
enable: boolean;
defaultPageSize: number = -1;
pageSize: number = -1;
currentPage: number = 0;
constructor() {
let m = new BucketMatrix();
this.bucketMatrix = m;
}
// An array of row labels for current page.
targets(): string[] {
if (!this.enable) {
return this.bucketMatrix.targets;
}
return this.bucketMatrix.targets.slice(this.pageSize * this.currentPage, this.pageSize * (this.currentPage+1) );
}
buckets(): {[yLabel: string]: Bucket[]} {
if (!this.enable) {
return this.bucketMatrix.buckets;
}
let buckets: {[yLabel: string]: Bucket[]} = {}
let me = this;
this.targets().map(function (rowLabel) {
buckets[rowLabel] = me.bucketMatrix.buckets[rowLabel];
})
return buckets;
}
setEnable(enable: boolean) {
this.enable = enable;
}
setCurrent(num: number): void {
this.currentPage = num;
}
setDefaultPageSize(num: number): void {
this.defaultPageSize = num;
}
setPageSize(num: number): void {
this.pageSize = num;
}
pages(): number {
return Math.ceil(this.totalRows() / this.pageSize);
}
totalRows(): number {
return this.bucketMatrix.targets.length;
}
pageStartRow(): number {
if (!this.enable) {
return 1;
}
return (this.pageSize * this.currentPage) + 1;
}
pageEndRow(): number {
if (!this.enable) {
return this.totalRows();
}
let last = this.pageSize * (this.currentPage+1);
if (last > this.totalRows()) {
return this.totalRows();
}
return last;
}
hasNext(): boolean {
if (!this.enable) {
return false;
}
if ((this.currentPage+1)*this.pageSize >= this.totalRows()) {
return false;
}
return true;
// currentPage >= ctrl.bucketMatrix.targets.length/ctrl.pageSizeViewer - 1 || ctrl.numberOfPages == 0
}
hasPrev(): boolean {
if (!this.enable) {
return false;
}
return this.currentPage > 0;
}
switchToNext() {
if (this.hasNext()) {
this.currentPage = this.currentPage + 1;
}
}
switchToPrev() {
if (this.hasPrev()) {
this.currentPage = this.currentPage - 1;
}
}
}
export {Bucket, BucketMatrix, BucketMatrixPager };
-228
View File
@@ -1,228 +0,0 @@
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import { ExtraSeriesFormatValue } from './extra_series_format';
const TOOLTIP_PADDING_X = -50;
const TOOLTIP_PADDING_Y = 5;
export class StatusHeatmapTooltipExtraSeries {
scope: any;
dashboard: any;
panelCtrl: any;
panel: any;
heatmapPanel: any;
mouseOverBucket: any;
originalFillColor: any;
tooltip: any;
constructor(elem: any, scope: any) {
this.scope = scope;
this.dashboard = scope.ctrl.dashboard;
this.panelCtrl = scope.ctrl;
this.panel = scope.ctrl.panel;
this.heatmapPanel = elem;
this.mouseOverBucket = false;
this.originalFillColor = null;
elem.on("mouseover", this.onMouseOver.bind(this));
elem.on("click", this.onMouseClick.bind(this));
}
public onMouseOver(e: Event) {
if (!this.panel.usingUrl || !this.scope.ctrl.data || _.isEmpty(this.scope.ctrl.data)) {
return;
}
}
public onMouseClick(e: Event) {
if (!this.panel.usingUrl) {
return;
}
this.destroy();
this.add();
}
public add() {
this.tooltip = d3.select("body")
.append("div")
.attr("class", "statusmap-tooltip-extraseries graph-tooltip grafana-tooltip");
}
public destroy() {
if (this.tooltip) {
this.tooltip.remove();
}
this.tooltip = null;
}
public show(pos: any) {
if (!this.panel.usingUrl || !this.tooltip) {
return;
}
// shared tooltip mode
if (pos.panelRelY) {
return;
}
let cardId: any = d3.select(pos.target).attr('cardId');
if (!cardId) {
this.destroy();
return;
}
let card: any;
if (this.panel.usingPagination) {
card = this.panelCtrl.cardsDataComplete[cardId];
} else {
card = this.panelCtrl.cardsData.cards[cardId];
}
if (!card) {
this.destroy();
return;
}
if (card.value == null) {
this.destroy();
return;
}
let x: any = card.x;
let y: any = card.y;
let value: any = card.value;
let values: any = card.values;
let tooltipTimeFormat: string = 'YYYY-MM-DD HH:mm:ss';
let time: Date = this.dashboard.formatDate(+x, tooltipTimeFormat);
let tooltipHtml: string = `<div class="graph-tooltip-time">${time}</div>`
if (this.panel.color.mode === 'discrete') {
let statuses: any = "";
if (this.panelCtrl.panel.seriesFilterIndex == -1) {
statuses = this.panelCtrl.discreteExtraSeries.convertValuesToTooltips(values);
} else {
statuses = this.panelCtrl.discreteExtraSeries.convertValueToTooltips(value);
}
tooltipHtml += `
<div>
name: <b>${y}</b>
<div>
<br>
<span>status:</span>
<ul>
${_.join(_.map(statuses, v => `<p style="background-color: ${v.color}; text-align:center" class="discrete-item">${v.tooltip}</p>`), "")}
</ul>
</div>
</div> <br>`;
}
tooltipHtml += `<div class="statusmap-histogram"></div>`;
let urls: any = this.panelCtrl.panel.urls
let rtime: any = this.panelCtrl.retrieveTimeVar();
let curl: any = JSON.parse(JSON.stringify(urls));
for (let i = 0; i < curl.length; i++) {
//Change name var
curl[i].base_url = _.replace(curl[i].base_url, /\$series_label/g, y)
//Set up extra series
if (curl[i].useExtraSeries == true) {
let tf: any = curl[i].extraSeries.format
let vh: any = card.values[curl[i].extraSeries.index]
//let extraSeries: any = this.dashboard.formatDate(+vh, tf)
let series_extra: any = this.formatExtraSeries(vh,tf);
curl[i].base_url = _.replace(curl[i].base_url, /\$series_extra/g, series_extra)
}
//Change time var
curl[i].base_url = _.replace(curl[i].base_url, /\$time/g, rtime)
//Replace vars
curl[i].base_url = this.panelCtrl.renderLink(curl[i].base_url, this.panelCtrl.variableSrv.variables)
}
if (this.panelCtrl.panel.usingUrl == true) {
tooltipHtml += `
<div bs-tooltip='Settings' data-placement="right">
${_.join(_.map(curl, v => `<div ><a href="${v.forcelowercase ? v.base_url.toLowerCase() : v.base_url}" target="_blank"><div class="dashlist-item">
<p class="dashlist-link dashlist-link-dash-db"><span style="word-wrap: break-word;" class="dash-title">${v.label ? v.label : (v.base_url != "" ? _.truncate(v.base_url) : "Empty URL" )}</span><span class="dashlist-star">
<i class="fa fa-${v.icon_fa}"></i>
</span></p> </div></a><div>`), "")}
</div> <br>`;
}
// "Ambiguous bucket state: Multiple values!";
if (!this.panel.useMax && card.multipleValues) {
tooltipHtml += `<div><b>Error:</b> ${this.panelCtrl.dataWarnings.multipleValues.title}</div>`;
}
// Discrete mode errors
if (this.panel.color.mode === 'discrete') {
if (card.noColorDefined) {
let badValues: any = this.panelCtrl.discreteExtraSeries.getNotColoredValues(values);
tooltipHtml += `<div><b>Error:</b> ${this.panelCtrl.dataWarnings.noColorDefined.title}
<br>not colored values:
<ul>
${_.join(_.map(badValues, v => `<li>${v}</li>`), "")}
</ul>
</div>`;
}
}
this.tooltip.html(tooltipHtml);
this.move(pos);
}
public formatExtraSeries (value: any, type: any) {
let extraSeries: any = '';
switch(type) {
case ExtraSeriesFormatValue.Date:
extraSeries = this.dashboard.formatDate(+value, type);
return extraSeries;
case ExtraSeriesFormatValue.Raw:
extraSeries = value;
return extraSeries;
default:
return extraSeries;
}
}
public move(pos: any) {
if (!this.tooltip) {
return;
}
let elem: any = $(this.tooltip.node())[0];
let tooltipWidth = elem.clientWidth;
let tooltipHeight = elem.clientHeight;
let left = pos.pageX + TOOLTIP_PADDING_X;
let top = pos.pageY + TOOLTIP_PADDING_Y;
if (pos.pageX + tooltipWidth + 40 > window.innerWidth) {
left = pos.pageX - tooltipWidth - TOOLTIP_PADDING_X;
}
if (pos.pageY - window.pageYOffset + tooltipHeight + 20 > window.innerHeight) {
top = pos.pageY - tooltipHeight - TOOLTIP_PADDING_Y;
}
return this.tooltip
.style("left", left + "px")
.style("top", top + "px");
}
}