| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- ///<reference path="../../../headers/common.d.ts" />
- import _ from "lodash";
- import $ from "jquery";
- import { MetricsPanelCtrl } from "app/plugins/sdk";
- import { transformDataToTable } from "./transformers";
- import { tablePanelEditor } from "./editor";
- import { columnOptionsTab } from "./column_options";
- import { TableRenderer } from "./renderer";
- class TablePanelCtrl extends MetricsPanelCtrl {
- static templateUrl = "module.html";
- pageIndex: number;
- dataRaw: any;
- table: any;
- renderer: any;
- panelDefaults = {
- targets: [{}],
- transform: "timeseries_to_columns",
- pageSize: null,
- showHeader: true,
- styles: [
- {
- type: "date",
- pattern: "Time",
- alias: "Time",
- dateFormat: "YYYY-MM-DD HH:mm:ss"
- },
- {
- unit: "short",
- type: "number",
- alias: "",
- decimals: 2,
- colors: [
- "rgba(245, 54, 54, 0.9)",
- "rgba(237, 129, 40, 0.89)",
- "rgba(50, 172, 45, 0.97)"
- ],
- colorMode: null,
- pattern: "/.*/",
- thresholds: []
- }
- ],
- columns: [],
- scroll: true,
- fontSize: "100%",
- sort: { col: 0, desc: true }
- };
- /** @ngInject */
- constructor(
- $scope,
- $injector,
- templateSrv,
- private annotationsSrv,
- private $sanitize,
- private variableSrv
- ) {
- super($scope, $injector);
- this.pageIndex = 0;
- if (this.panel.styles === void 0) {
- this.panel.styles = this.panel.columns;
- this.panel.columns = this.panel.fields;
- delete this.panel.columns;
- delete this.panel.fields;
- }
- _.defaults(this.panel, this.panelDefaults);
- this.events.on("data-received", this.onDataReceived.bind(this));
- this.events.on("data-error", this.onDataError.bind(this));
- this.events.on("data-snapshot-load", this.onDataReceived.bind(this));
- this.events.on("init-edit-mode", this.onInitEditMode.bind(this));
- this.events.on("init-panel-actions", this.onInitPanelActions.bind(this));
- }
- onInitEditMode() {
- this.addEditorTab("Options", tablePanelEditor, 2);
- this.addEditorTab("Column Styles", columnOptionsTab, 3);
- }
- onInitPanelActions(actions) {
- actions.push({ text: "Export CSV", click: "ctrl.exportCsv()" });
- }
- issueQueries(datasource) {
- this.pageIndex = 0;
- if (this.panel.transform === "annotations") {
- this.setTimeQueryStart();
- return this.annotationsSrv
- .getAnnotations({
- dashboard: this.dashboard,
- panel: this.panel,
- range: this.range
- })
- .then(annotations => {
- return { data: annotations };
- });
- }
- return super.issueQueries(datasource);
- }
- onDataError(err) {
- this.dataRaw = [];
- this.render();
- }
- onDataReceived(dataList) {
- this.dataRaw = dataList;
- this.pageIndex = 0;
- // automatically correct transform mode based on data
- if (this.dataRaw && this.dataRaw.length) {
- if (this.dataRaw[0].type === "table") {
- this.panel.transform = "table";
- } else {
- if (this.dataRaw[0].type === "docs") {
- this.panel.transform = "json";
- } else {
- if (
- this.panel.transform === "table" ||
- this.panel.transform === "json"
- ) {
- this.panel.transform = "timeseries_to_rows";
- }
- }
- }
- }
- this.render();
- }
- render() {
- this.table = transformDataToTable(this.dataRaw, this.panel);
- this.table.sort(this.panel.sort);
- this.renderer = new TableRenderer(
- this.panel,
- this.table,
- this.dashboard.isTimezoneUtc(),
- this.$sanitize,
- this.templateSrv
- );
- return super.render(this.table);
- }
- toggleColumnSort(col, colIndex) {
- // remove sort flag from current column
- if (this.table.columns[this.panel.sort.col]) {
- this.table.columns[this.panel.sort.col].sort = false;
- }
- if (this.panel.sort.col === colIndex) {
- if (this.panel.sort.desc) {
- this.panel.sort.desc = false;
- } else {
- this.panel.sort.col = null;
- }
- } else {
- this.panel.sort.col = colIndex;
- this.panel.sort.desc = true;
- }
- this.render();
- }
- exportCsv() {
- var scope = this.$scope.$new(true);
- scope.tableData = this.renderer.render_values();
- scope.panel = "table";
- this.publishAppEvent("show-modal", {
- templateHtml:
- '<export-data-modal panel="panel" data="tableData"></export-data-modal>',
- scope,
- modalClass: "modal--narrow"
- });
- }
- link(scope, elem, attrs, ctrl: TablePanelCtrl) {
- var data;
- var panel = ctrl.panel;
- var pageCount = 0;
- function getTableHeight() {
- var panelHeight = ctrl.height;
- if (pageCount > 1) {
- panelHeight -= 26;
- }
- return panelHeight - 31 + "px";
- }
- function appendTableRows(tbodyElem) {
- ctrl.renderer.setTable(data);
- tbodyElem.empty();
- tbodyElem.html(ctrl.renderer.render(ctrl.pageIndex));
- }
- function switchPage(e) {
- var el = $(e.currentTarget);
- ctrl.pageIndex = parseInt(el.text(), 10) - 1;
- renderPanel();
- }
- function appendPaginationControls(footerElem) {
- footerElem.empty();
- var pageSize = panel.pageSize || 100;
- pageCount = Math.ceil(data.rows.length / pageSize);
- if (pageCount === 1) {
- return;
- }
- var startPage = Math.max(ctrl.pageIndex - 3, 0);
- var endPage = Math.min(pageCount, startPage + 9);
- var paginationList = $("<ul></ul>");
- for (var i = startPage; i < endPage; i++) {
- var activeClass = i === ctrl.pageIndex ? "active" : "";
- var pageLinkElem = $(
- '<li><a class="table-panel-page-link pointer ' +
- activeClass +
- '">' +
- (i + 1) +
- "</a></li>"
- );
- paginationList.append(pageLinkElem);
- }
- footerElem.append(paginationList);
- }
- function renderPanel() {
- var panelElem = elem.parents(".panel");
- var rootElem = elem.find(".table-panel-scroll");
- var tbodyElem = elem.find("tbody");
- var footerElem = elem.find(".table-panel-footer");
- elem.css({ "font-size": panel.fontSize });
- panelElem.addClass("table-panel-wrapper");
- appendTableRows(tbodyElem);
- appendPaginationControls(footerElem);
- rootElem.css({ "max-height": panel.scroll ? getTableHeight() : "" });
- }
- // hook up link tooltips
- elem.tooltip({
- selector: "[data-link-tooltip]"
- });
- function addFilterClicked(e) {
- let filterData = $(e.currentTarget).data();
- var options = {
- datasource: panel.datasource,
- key: data.columns[filterData.column].text,
- value: data.rows[filterData.row][filterData.column],
- operator: filterData.operator
- };
- ctrl.variableSrv.setAdhocFilter(options);
- }
- elem.on("click", ".table-panel-page-link", switchPage);
- elem.on("click", ".table-panel-filter-link", addFilterClicked);
- var unbindDestroy = scope.$on("$destroy", function() {
- elem.off("click", ".table-panel-page-link");
- elem.off("click", ".table-panel-filter-link");
- unbindDestroy();
- });
- ctrl.events.on("render", function(renderData) {
- data = renderData || data;
- if (data) {
- renderPanel();
- }
- ctrl.renderingCompleted();
- });
- }
- }
- export { TablePanelCtrl, TablePanelCtrl as PanelCtrl };
|