From b1691f1cd13ccf93bc36199c52fe018c7316ace0 Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Thu, 27 Apr 2017 15:23:49 -0400 Subject: [PATCH 01/16] add support for column aliases in table panel --- public/app/plugins/panel/table/editor.html | 102 ++++++++++++--------- public/app/plugins/panel/table/editor.ts | 1 + public/app/plugins/panel/table/module.html | 2 +- public/app/plugins/panel/table/module.ts | 21 +++++ public/app/plugins/panel/table/renderer.ts | 56 ++++++----- 5 files changed, 114 insertions(+), 68 deletions(-) diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 448669ca6a9..561645b7118 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -67,20 +67,38 @@ -
- - +
+ +
-
- + +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+ +
+
@@ -94,41 +112,41 @@
-
+
- -
- -
-
-
-
-
- + +
+ +
+ +
+
+
+ -
-
- - -
-
- - - - - - - - - - -
-
-
- Invert -
-
-
+
+
+ + +
+
+ + + + + + + + + + +
+
+
+ Invert +
+
+
diff --git a/public/app/plugins/panel/table/editor.ts b/public/app/plugins/panel/table/editor.ts index 6b803cc0444..9f36c88c986 100644 --- a/public/app/plugins/panel/table/editor.ts +++ b/public/app/plugins/panel/table/editor.ts @@ -107,6 +107,7 @@ export class TablePanelEditorCtrl { var columnStyleDefaults = { 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, diff --git a/public/app/plugins/panel/table/module.html b/public/app/plugins/panel/table/module.html index e405c6c42e3..226fe095ca3 100644 --- a/public/app/plugins/panel/table/module.html +++ b/public/app/plugins/panel/table/module.html @@ -7,7 +7,7 @@
- {{col.text}} + {{col.title || col.text}} diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index bf872b47d27..155934dc85e 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -9,6 +9,7 @@ import {MetricsPanelCtrl} from 'app/plugins/sdk'; import {transformDataToTable} from './transformers'; import {tablePanelEditor} from './editor'; import {TableRenderer} from './renderer'; +import kbn from 'app/core/utils/kbn'; class TablePanelCtrl extends MetricsPanelCtrl { static templateUrl = 'module.html'; @@ -26,11 +27,13 @@ class TablePanelCtrl extends MetricsPanelCtrl { { 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, @@ -118,6 +121,24 @@ class TablePanelCtrl extends MetricsPanelCtrl { render() { this.table = transformDataToTable(this.dataRaw, this.panel); this.table.sort(this.panel.sort); + + for (let colIndex = 0; colIndex < this.table.columns.length; colIndex++) { + let column = this.table.columns[colIndex]; + + for (let i = 0; i < this.panel.styles.length; i++) { + let style = this.panel.styles[i]; + var regex = kbn.stringToJsRegex(style.pattern); + const matches = column.text.match(regex); + if (matches) { + column.style = style; + if (style.alias) { + column.title = column.text.replace(regex, style.alias); + } + break; + } + } + } + return super.render(this.table); } diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index 2f5a51ab111..f51af0a0de4 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -24,7 +24,7 @@ export class TableRenderer { return _.first(style.colors); } - defaultCellFormater(v, style) { + defaultCellFormatter(v, style) { if (v === null || v === void 0 || v === undefined) { return ''; } @@ -40,18 +40,18 @@ export class TableRenderer { } } - createColumnFormater(style, column) { - if (!style) { - return this.defaultCellFormater; + createColumnFormatter(column) { + if (!column.style) { + return this.defaultCellFormatter; } - if (style.type === 'hidden') { + if (column.style.type === 'hidden') { return v => { return undefined; }; } - if (style.type === 'date') { + if (column.style.type === 'date') { return v => { if (v === undefined || v === null) { return '-'; @@ -62,12 +62,12 @@ export class TableRenderer { if (this.isUtc) { date = date.utc(); } - return date.format(style.dateFormat); + return date.format(column.style.dateFormat); }; } - if (style.type === 'number') { - let valueFormater = kbn.valueFormats[column.unit || style.unit]; + if (column.style.type === 'number') { + let valueFormatter = kbn.valueFormats[column.unit || column.style.unit]; return v => { if (v === null || v === void 0) { @@ -75,38 +75,44 @@ export class TableRenderer { } if (_.isString(v)) { - return this.defaultCellFormater(v, style); + return this.defaultCellFormatter(v, column.style); } - if (style.colorMode) { - this.colorState[style.colorMode] = this.getColorForValue(v, style); + if (column.style.colorMode) { + this.colorState[column.style.colorMode] = this.getColorForValue(v, column.style); } - return valueFormater(v, style.decimals, null); + return valueFormatter(v, column.style.decimals, null); }; } return (value) => { - return this.defaultCellFormater(value, style); + return this.defaultCellFormatter(value, column.style); }; } formatColumnValue(colIndex, value) { - if (this.formaters[colIndex]) { - return this.formaters[colIndex](value); - } - - for (let i = 0; i < this.panel.styles.length; i++) { - let style = this.panel.styles[i]; + if (!this.formaters[colIndex]) { let column = this.table.columns[colIndex]; - var regex = kbn.stringToJsRegex(style.pattern); - if (column.text.match(regex)) { - this.formaters[colIndex] = this.createColumnFormater(style, column); - return this.formaters[colIndex](value); + + if (!column.style) { + for (let i = 0; i < this.panel.styles.length; i++) { + let style = this.panel.styles[i]; + var regex = kbn.stringToJsRegex(style.pattern); + const matches = column.text.match(regex); + if (matches) { + column.style = style; + if (style.alias) { + column.title = column.text.replace(regex, style.alias); + } + break; + } + } } + + this.formaters[colIndex] = this.createColumnFormatter(column); } - this.formaters[colIndex] = this.defaultCellFormater; return this.formaters[colIndex](value); } From 2361e2ddd9484e95095fa85775f352d994a2fe62 Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Thu, 27 Apr 2017 15:24:05 -0400 Subject: [PATCH 02/16] fix moment.js deprecation warning when running tests --- public/app/plugins/panel/heatmap/specs/renderer_specs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts index 3467c5b7542..3bb3c04d122 100644 --- a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts +++ b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts @@ -81,8 +81,8 @@ describe('grafanaHeatmap', function () { getTimezone: sinon.stub().returns('utc') }, range: { - from: moment.utc("01 Mar 2017 10:00:00"), - to: moment.utc("01 Mar 2017 11:00:00"), + from: moment.utc("01 Mar 2017 10:00:00", 'DD MMM YYYY HH:mm:ss'), + to: moment.utc("01 Mar 2017 11:00:00", 'DD MMM YYYY HH:mm:ss'), }, }; @@ -263,5 +263,5 @@ function getTicks(element, axisSelector) { function formatLocalTime(timeStr) { let format = "HH:mm"; - return moment.utc(timeStr).local().format(format); + return moment.utc(timeStr, 'DD MMM YYYY HH:mm:ss').local().format(format); } From 29653d2becfb677cfeecb7563c8bca36ac11c225 Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Fri, 5 May 2017 12:40:49 -0400 Subject: [PATCH 03/16] refactor and add column alias tests --- public/app/core/utils/file_export.ts | 2 +- public/app/plugins/panel/table/module.html | 2 +- public/app/plugins/panel/table/module.ts | 25 ++------ public/app/plugins/panel/table/renderer.ts | 61 +++++++++++-------- .../panel/table/specs/renderer_specs.ts | 18 +++++- .../app/plugins/panel/table/transformers.ts | 3 +- 6 files changed, 61 insertions(+), 50 deletions(-) diff --git a/public/app/core/utils/file_export.ts b/public/app/core/utils/file_export.ts index f2f0192e034..24b501eee28 100644 --- a/public/app/core/utils/file_export.ts +++ b/public/app/core/utils/file_export.ts @@ -53,7 +53,7 @@ export function exportTableDataToCsv(table) { var text = 'sep=;\n'; // add header _.each(table.columns, function(column) { - text += column.text + ';'; + text += (column.title || column.text) + ';'; }); text += '\n'; // process data diff --git a/public/app/plugins/panel/table/module.html b/public/app/plugins/panel/table/module.html index 226fe095ca3..5c6fcbfdb1e 100644 --- a/public/app/plugins/panel/table/module.html +++ b/public/app/plugins/panel/table/module.html @@ -7,7 +7,7 @@
- {{col.title || col.text}} + {{col.title}} diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index 155934dc85e..e8e3cae1a6b 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -17,6 +17,7 @@ class TablePanelCtrl extends MetricsPanelCtrl { pageIndex: number; dataRaw: any; table: any; + renderer: any; panelDefaults = { targets: [{}], @@ -122,22 +123,7 @@ class TablePanelCtrl extends MetricsPanelCtrl { this.table = transformDataToTable(this.dataRaw, this.panel); this.table.sort(this.panel.sort); - for (let colIndex = 0; colIndex < this.table.columns.length; colIndex++) { - let column = this.table.columns[colIndex]; - - for (let i = 0; i < this.panel.styles.length; i++) { - let style = this.panel.styles[i]; - var regex = kbn.stringToJsRegex(style.pattern); - const matches = column.text.match(regex); - if (matches) { - column.style = style; - if (style.alias) { - column.title = column.text.replace(regex, style.alias); - } - break; - } - } - } + this.renderer = new TableRenderer(this.panel, this.table, this.dashboard.isTimezoneUtc(), this.$sanitize); return super.render(this.table); } @@ -162,8 +148,7 @@ class TablePanelCtrl extends MetricsPanelCtrl { } exportCsv() { - var renderer = new TableRenderer(this.panel, this.table, this.dashboard.isTimezoneUtc(), this.$sanitize); - FileExport.exportTableDataToCsv(renderer.render_values()); + FileExport.exportTableDataToCsv(this.renderer.render_values()); } link(scope, elem, attrs, ctrl) { @@ -183,9 +168,9 @@ class TablePanelCtrl extends MetricsPanelCtrl { } function appendTableRows(tbodyElem) { - var renderer = new TableRenderer(panel, data, ctrl.dashboard.isTimezoneUtc(), ctrl.$sanitize); + ctrl.renderer.setTable(data); tbodyElem.empty(); - tbodyElem.html(renderer.render(ctrl.pageIndex)); + tbodyElem.html(ctrl.renderer.render(ctrl.pageIndex)); } function switchPage(e) { diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index f51af0a0de4..ae56e8dff12 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -5,12 +5,44 @@ import moment from 'moment'; import kbn from 'app/core/utils/kbn'; export class TableRenderer { - formaters: any[]; + formatters: any[]; colorState: any; constructor(private panel, private table, private isUtc, private sanitize) { - this.formaters = []; + this.initColumns(); + } + + setTable(table) { + this.table = table; + + this.initColumns(); + } + + initColumns() { + this.formatters = []; this.colorState = {}; + + for (let colIndex = 0; colIndex < this.table.columns.length; colIndex++) { + let column = this.table.columns[colIndex]; + column.title = column.text; + + for (let i = 0; i < this.panel.styles.length; i++) { + let style = this.panel.styles[i]; + + var regex = kbn.stringToJsRegex(style.pattern); + if (column.text.match(regex)) { + column.style = style; + + if (style.alias) { + column.title = column.text.replace(regex, style.alias); + } + + break; + } + } + + this.formatters[colIndex] = this.createColumnFormatter(column); + } } getColorForValue(value, style) { @@ -92,28 +124,7 @@ export class TableRenderer { } formatColumnValue(colIndex, value) { - if (!this.formaters[colIndex]) { - let column = this.table.columns[colIndex]; - - if (!column.style) { - for (let i = 0; i < this.panel.styles.length; i++) { - let style = this.panel.styles[i]; - var regex = kbn.stringToJsRegex(style.pattern); - const matches = column.text.match(regex); - if (matches) { - column.style = style; - if (style.alias) { - column.title = column.text.replace(regex, style.alias); - } - break; - } - } - } - - this.formaters[colIndex] = this.createColumnFormatter(column); - } - - return this.formaters[colIndex](value); + return this.formatters[colIndex] ? this.formatters[colIndex](value) : value; } renderCell(columnIndex, value, addWidthHack = false) { @@ -132,7 +143,7 @@ export class TableRenderer { // this hack adds header content to cell (not visible) var widthHack = ''; if (addWidthHack) { - widthHack = '
' + this.table.columns[columnIndex].text + '
'; + widthHack = '
' + this.table.columns[columnIndex].title + '
'; } if (value === undefined) { diff --git a/public/app/plugins/panel/table/specs/renderer_specs.ts b/public/app/plugins/panel/table/specs/renderer_specs.ts index 46789f295d1..6b031d4bb91 100644 --- a/public/app/plugins/panel/table/specs/renderer_specs.ts +++ b/public/app/plugins/panel/table/specs/renderer_specs.ts @@ -22,13 +22,15 @@ describe('when rendering table', () => { { pattern: 'Time', type: 'date', - format: 'LLL' + format: 'LLL', + alias: 'Timestamp' }, { - pattern: 'Value', + pattern: '/(Val)ue/', type: 'number', unit: 'ms', decimals: 3, + alias: '$1' }, { pattern: 'Colored', @@ -132,6 +134,18 @@ describe('when rendering table', () => { var html = renderer.renderCell(6, 'text link'); expect(html).to.be('sanitized'); }); + + it('Time column title should be Timestamp', () => { + expect(table.columns[0].title).to.be('Timestamp'); + }); + + it('Value column title should be Val', () => { + expect(table.columns[1].title).to.be('Val'); + }); + + it('Colored column title should be Colored', () => { + expect(table.columns[2].title).to.be('Colored'); + }); }); }); diff --git a/public/app/plugins/panel/table/transformers.ts b/public/app/plugins/panel/table/transformers.ts index 15cc9e71134..0f793fa0434 100644 --- a/public/app/plugins/panel/table/transformers.ts +++ b/public/app/plugins/panel/table/transformers.ts @@ -229,7 +229,7 @@ function transformDataToTable(data, panel) { var transformer = transformers[panel.transform]; if (!transformer) { - throw {message: 'Transformer ' + panel.transformer + ' not found'}; + throw {message: 'Transformer ' + panel.transform + ' not found'}; } if (panel.filterNull) { @@ -239,6 +239,7 @@ function transformDataToTable(data, panel) { } transformer.transform(copyData, panel, model); + return model; } From e8fbfce59a7a32b38d121a7dd9fd045071987e9d Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Fri, 5 May 2017 13:11:44 -0400 Subject: [PATCH 04/16] remove unneeded import, update docs text --- docs/sources/features/panels/table_panel.md | 9 +++++---- public/app/plugins/panel/table/module.ts | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/sources/features/panels/table_panel.md b/docs/sources/features/panels/table_panel.md index 9ddc2cddaee..69cd02fdbcc 100644 --- a/docs/sources/features/panels/table_panel.md +++ b/docs/sources/features/panels/table_panel.md @@ -85,8 +85,9 @@ The column styles allow you control how dates and numbers are formatted. 1. `Name or regex`: The Name or Regex field controls what columns the rule should be applied to. The regex or name filter will be matched against the column name not against column values. 2. `Type`: The three supported types of types are `Number`, `String` and `Date`. -3. `Format`: Specify date format. Only available when `Type` is set to `Date`. -4. `Coloring` and `Thresholds`: Specify color mode and thresholds limits. -5. `Unit` and `Decimals`: Specify unit and decimal precision for numbers. -6. `Add column style rule`: Add new column rule. +3. `Title`: Title for the column, when using a Regex the title can include replacement strings like `$1`. +4. `Format`: Specify date format. Only available when `Type` is set to `Date`. +5. `Coloring` and `Thresholds`: Specify color mode and thresholds limits. +6. `Unit` and `Decimals`: Specify unit and decimal precision for numbers. +7. `Add column style rule`: Add new column rule. diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index e8e3cae1a6b..9b563ca5b18 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -9,7 +9,6 @@ import {MetricsPanelCtrl} from 'app/plugins/sdk'; import {transformDataToTable} from './transformers'; import {tablePanelEditor} from './editor'; import {TableRenderer} from './renderer'; -import kbn from 'app/core/utils/kbn'; class TablePanelCtrl extends MetricsPanelCtrl { static templateUrl = 'module.html'; From c323d2fc4cd89e3e59d9f821eb00884b590d541f Mon Sep 17 00:00:00 2001 From: lpavlovi Date: Sun, 7 May 2017 02:19:08 -0400 Subject: [PATCH 05/16] Removed panelElemName - appears to not be used anywhere (#8313) --- public/app/core/directives/plugin_component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/public/app/core/directives/plugin_component.ts b/public/app/core/directives/plugin_component.ts index 3e446b14b9e..4c098f60a4c 100644 --- a/public/app/core/directives/plugin_component.ts +++ b/public/app/core/directives/plugin_component.ts @@ -61,7 +61,6 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $ attrs: {dashboard: "ctrl.dashboard", panel: "panel", row: "ctrl.row"}, }; - var panelElemName = 'panel-' + scope.panel.type; let panelInfo = config.panels[scope.panel.type]; var panelCtrlPromise = Promise.resolve(UnknownPanelCtrl); if (panelInfo) { From e2f0b42d902a61fc936e8ecc8d4be0da5cac708e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 06:49:44 +0200 Subject: [PATCH 06/16] docs: updated cloudwatch docs, closes #8315 --- .../features/datasources/cloudwatch.md | 84 +++++++++++-------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/docs/sources/features/datasources/cloudwatch.md b/docs/sources/features/datasources/cloudwatch.md index c2896c5b172..8d77e5c59c0 100644 --- a/docs/sources/features/datasources/cloudwatch.md +++ b/docs/sources/features/datasources/cloudwatch.md @@ -13,29 +13,26 @@ weight = 10 # Using AWS CloudWatch in Grafana -Grafana ships with built in support for CloudWatch. You just have to add it as a data source and you will -be ready to build dashboards for you CloudWatch metrics. +Grafana ships with built in support for CloudWatch. You just have to add it as a data source and you will be ready to build dashboards for you CloudWatch metrics. -## Adding the data source -![](/img/docs/cloudwatch/cloudwatch_add.png) +## Adding the data source to Grafana -1. Open the side menu by clicking the the Grafana icon in the top header. +1. Open the side menu by clicking the Grafana icon in the top header. 2. In the side menu under the `Dashboards` link you should find a link named `Data Sources`. +3. Click the `+ Add data source` button in the top header. +4. Select `Cloudwatch` from the *Type* dropdown. - > NOTE: If this link is missing in the side menu it means that your current user does not have the `Admin` role for the current organization. - -3. Click the `Add new` link in the top header. -4. Select `CloudWatch` from the dropdown. - > NOTE: If at any moment you have issues with getting this datasource to work and grafana is giving you undescriptive errors then dont forget to check your log file (try looking in /var/log/grafana/). +> NOTE: If at any moment you have issues with getting this datasource to work and Grafana is giving you undescriptive errors then don't +forget to check your log file (try looking in /var/log/grafana/grafana.log). Name | Description ------------ | ------------- -Name | The data source name, important that this is the same as in Grafana v1.x if you plan to import old dashboards. -Default | Default data source means that it will be pre-selected for new panels. -Credentials profile name | Specify the name of the profile to use (if you use `~/aws/credentials` file), leave blank for default. This option was introduced in Grafana 2.5.1 -Default Region | Used in query editor to set region (can be changed on per query basis) -Custom Metrics namespace | Specify the CloudWatch namespace of Custom metrics -Assume Role Arn | Specify the ARN of the role to assume +*Name* | The data source name. This is how you refer to the data source in panels & queries. +*Default* | Default data source means that it will be pre-selected for new panels. +*Credentials* profile name | Specify the name of the profile to use (if you use `~/aws/credentials` file), leave blank for default. +*Default Region* | Used in query editor to set region (can be changed on per query basis) +*Custom Metrics namespace* | Specify the CloudWatch namespace of Custom metrics +*Assume Role Arn* | Specify the ARN of the role to assume ## Authentication @@ -61,49 +58,64 @@ Example content: ## Metric Query Editor -![](/img/docs/cloudwatch/query_editor.png) +![](/img/docs/v43/cloudwatch_editor.png) You need to specify a namespace, metric, at least one stat, and at least one dimension. ## Templated queries -CloudWatch Datasource Plugin provides the following functions in `Variables values query` field in Templating Editor to query `region`, `namespaces`, `metric names` and `dimension keys/values` on the CloudWatch. + +Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. +Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data +being displayed in your dashboard. + +Checkout the [Templating]({{< relref "reference/templating.md" >}}) documentation for an introduction to the templating feature and the different +types of template variables. + +### Query variable + +CloudWatch Datasource Plugin provides the following queries you can specify in the `Query` field in the Variable +edit view. They allow you to fill a variable's options list with things like `region`, `namespaces`, `metric names` +and `dimension keys/values`. Name | Description ------- | -------- -`regions()` | Returns a list of regions AWS provides their service. -`namespaces()` | Returns a list of namespaces CloudWatch support. -`metrics(namespace, [region])` | Returns a list of metrics in the namespace. (specify region for custom metrics) -`dimension_keys(namespace)` | Returns a list of dimension keys in the namespace. -`dimension_values(region, namespace, metric, dimension_key)` | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`. -`ebs_volume_ids(region, instance_id)` | Returns a list of volume id matching the specified `region`, `instance_id`. -`ec2_instance_attribute(region, attribute_name, filters)` | Returns a list of attribute matching the specified `region`, `attribute_name`, `filters`. +*regions()* | Returns a list of regions AWS provides their service. +*namespaces()* | Returns a list of namespaces CloudWatch support. +*metrics(namespace, [region])* | Returns a list of metrics in the namespace. (specify region for custom metrics) +*dimension_keys(namespace)* | Returns a list of dimension keys in the namespace. +*dimension_values(region, namespace, metric, dimension_key)* | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`. +*ebs_volume_ids(region, instance_id)* | Returns a list of volume id matching the specified `region`, `instance_id`. +*ec2_instance_attribute(region, attribute_name, filters)* | Returns a list of attribute matching the specified `region`, `attribute_name`, `filters`. For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html). -## Example templated Queries +#### Examples templated Queries Example dimension queries which will return list of resources for individual AWS Services: -Service | Query +Query | Service ------- | ----- -ELB | `dimension_values(us-east-1,AWS/ELB,RequestCount,LoadBalancerName)` -ElastiCache | `dimension_values(us-east-1,AWS/ElastiCache,CPUUtilization,CacheClusterId)` -RedShift | `dimension_values(us-east-1,AWS/Redshift,CPUUtilization,ClusterIdentifier)` -RDS | `dimension_values(us-east-1,AWS/RDS,CPUUtilization,DBInstanceIdentifier)` -S3 | `dimension_values(us-east-1,AWS/S3,BucketSizeBytes,BucketName)` +*dimension_values(us-east-1,AWS/ELB,RequestCount,LoadBalancerName)* | ELB +*dimension_values(us-east-1,AWS/ElastiCache,CPUUtilization,CacheClusterId)* | ElastiCache +*dimension_values(us-east-1,AWS/Redshift,CPUUtilization,ClusterIdentifier)* | RedShift +*dimension_values(us-east-1,AWS/RDS,CPUUtilization,DBInstanceIdentifier)* | RDS +*dimension_values(us-east-1,AWS/S3,BucketSizeBytes,BucketName)* | S3 -## ec2_instance_attribute JSON filters +#### ec2_instance_attribute JSON filters The `ec2_instance_attribute` query take `filters` in JSON format. You can specify [pre-defined filters of ec2:DescribeInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html). -Specify like `{ filter_name1: [ filter_value1 ], filter_name2: [ filter_value2 ] }` + +Filters syntax: + +```javascript +{ filter_name1: [ filter_value1 ], filter_name2: [ filter_value2 ] } +``` Example `ec2_instance_attribute()` query ec2_instance_attribute(us-east-1, InstanceId, { "tag:Environment": [ "production" ] }) -![](/img/docs/v2/cloudwatch_templating.png) - ## Cost Amazon provides 1 million CloudWatch API requests each month at no additional charge. Past this, From 823b40a360b1403639727fa74e8406eef9b03adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 08:02:08 +0200 Subject: [PATCH 07/16] docs: added bash and http syntax highlighting --- docs/sources/http_api/dashboard.md | 142 +++++++++++++++------------- docs/sources/installation/debian.md | 42 +++++--- 2 files changed, 106 insertions(+), 78 deletions(-) diff --git a/docs/sources/http_api/dashboard.md b/docs/sources/http_api/dashboard.md index 053d4a8d329..a7b7ae87a62 100644 --- a/docs/sources/http_api/dashboard.md +++ b/docs/sources/http_api/dashboard.md @@ -19,26 +19,28 @@ Creates a new dashboard or updates an existing dashboard. **Example Request for new dashboard**: - POST /api/dashboards/db HTTP/1.1 - Accept: application/json - Content-Type: application/json - Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +```http +POST /api/dashboards/db HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk - { - "dashboard": { - "id": null, - "title": "Production Overview", - "tags": [ "templated" ], - "timezone": "browser", - "rows": [ - { - } - ], - "schemaVersion": 6, - "version": 0 - }, - "overwrite": false - } +{ + "dashboard": { + "id": null, + "title": "Production Overview", + "tags": [ "templated" ], + "timezone": "browser", + "rows": [ + { + } + ], + "schemaVersion": 6, + "version": 0 + }, + "overwrite": false +} +``` JSON Body schema: @@ -47,15 +49,17 @@ JSON Body schema: **Example Response**: - HTTP/1.1 200 OK - Content-Type: application/json; charset=UTF-8 - Content-Length: 78 +```http +HTTP/1.1 200 OK +Content-Type: application/json; charset=UTF-8 +Content-Length: 78 - { - "slug": "production-overview", - "status": "success", - "version": 1 - } +{ + "slug": "production-overview", + "status": "success", + "version": 1 +} +``` Status Codes: @@ -67,14 +71,16 @@ Status Codes: The **412** status code is used when a newer dashboard already exists (newer, its version is greater than the version that was sent). The same status code is also used if another dashboard exists with the same title. The response body will look like this: - HTTP/1.1 412 Precondition Failed - Content-Type: application/json; charset=UTF-8 - Content-Length: 97 +```http +HTTP/1.1 412 Precondition Failed +Content-Type: application/json; charset=UTF-8 +Content-Length: 97 - { - "message": "The dashboard has been changed by someone else", - "status": "version-mismatch" - } +{ + "message": "The dashboard has been changed by someone else", + "status": "version-mismatch" +} +``` In in case of title already exists the `status` property will be `name-exists`. @@ -86,34 +92,38 @@ Will return the dashboard given the dashboard slug. Slug is the url friendly ver **Example Request**: - GET /api/dashboards/db/production-overview HTTP/1.1 - Accept: application/json - Content-Type: application/json - Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +```http +GET /api/dashboards/db/production-overview HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` **Example Response**: - HTTP/1.1 200 - Content-Type: application/json +```http +HTTP/1.1 200 +Content-Type: application/json - { - "meta": { - "isStarred": false, - "slug": "production-overview" - }, - "dashboard": { - "id": null, - "title": "Production Overview", - "tags": [ "templated" ], - "timezone": "browser", - "rows": [ - { - } - ], - "schemaVersion": 6, - "version": 0 +{ + "meta": { + "isStarred": false, + "slug": "production-overview" + }, + "dashboard": { + "id": null, + "title": "Production Overview", + "tags": [ "templated" ], + "timezone": "browser", + "rows": [ + { } - } + ], + "schemaVersion": 6, + "version": 0 + } +} +``` ## Delete dashboard @@ -123,17 +133,21 @@ The above will delete the dashboard with the specified slug. The slug is the url **Example Request**: - DELETE /api/dashboards/db/test HTTP/1.1 - Accept: application/json - Content-Type: application/json - Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +```http +DELETE /api/dashboards/db/test HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` **Example Response**: - HTTP/1.1 200 - Content-Type: application/json +```http +HTTP/1.1 200 +Content-Type: application/json - {"title": "Test"} +{"title": "Test"} +``` ## Gets the home dashboard diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index 2071ff1b79c..7bbf8c2052f 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -22,10 +22,10 @@ installation. ## Install Stable -``` -$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.2.0_amd64.deb -$ sudo apt-get install -y adduser libfontconfig -$ sudo dpkg -i grafana_4.2.0_amd64.deb +```bash +wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.2.0_amd64.deb +sudo apt-get install -y adduser libfontconfig +sudo dpkg -i grafana_4.2.0_amd64.deb ``` ## APT Repository @@ -43,18 +43,24 @@ candidates. Then add the [Package Cloud](https://packagecloud.io/grafana) key. This allows you to install signed packages. - $ curl https://packagecloud.io/gpg.key | sudo apt-key add - +```bash +curl https://packagecloud.io/gpg.key | sudo apt-key add - +``` Update your Apt repositories and install Grafana - $ sudo apt-get update - $ sudo apt-get install grafana +```bash +sudo apt-get update +sudo apt-get install grafana +``` On some older versions of Ubuntu and Debian you may need to install the `apt-transport-https` package which is needed to fetch packages over HTTPS. - $ sudo apt-get install -y apt-transport-https +```bash +sudo apt-get install -y apt-transport-https +``` ## Package details @@ -70,7 +76,9 @@ HTTPS. Start Grafana by running: - $ sudo service grafana-server start +```bash +sudo service grafana-server start +``` This will start the `grafana-server` process as the `grafana` user, which was created during the package installation. The default HTTP port @@ -78,19 +86,25 @@ is `3000` and default user and group is `admin`. To configure the Grafana server to start at boot time: - $ sudo update-rc.d grafana-server defaults +```bash +sudo update-rc.d grafana-server defaults +``` ## Start the server (via systemd) To start the service using systemd: - $ systemctl daemon-reload - $ systemctl start grafana-server - $ systemctl status grafana-server +```bash +systemctl daemon-reload +systemctl start grafana-server +systemctl status grafana-server +``` Enable the systemd service so that Grafana starts at boot. - sudo systemctl enable grafana-server.service +```bash +sudo systemctl enable grafana-server.service +``` ## Environment file From 556829eda9bd9c06fa77b7acacdbbcfb14aeecb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 11:17:29 +0200 Subject: [PATCH 08/16] table: began table options redesign --- public/app/plugins/panel/table/editor.html | 141 +++++++++++---------- public/app/plugins/panel/table/editor.ts | 5 +- public/sass/components/_tabs.scss | 9 ++ 3 files changed, 85 insertions(+), 70 deletions(-) diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 561645b7118..657771d8338 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -52,58 +52,62 @@
-
-
-
Column Styles
-
+
+ Style Rules + +
+ + + +
+ +
+
+
+ + +
+
+ +
+ +
+
+
+
+ + +
+
+ +
+
Date options
+
+ + +
+
+ +
+
String options
+ +
+ +
+ +
+
Number options
+
- - -
-
- -
- -
-
-
- - -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
- -
-
-
-
- -
-
@@ -113,22 +117,23 @@
+
+
+ +
+
Thresholds & Coloring
+
+
+ + +
-
-
-
-
-
-
- - -
@@ -140,19 +145,17 @@ -
-
-
+
+
+
-
-
-
- -
+ +
+
diff --git a/public/app/plugins/panel/table/editor.ts b/public/app/plugins/panel/table/editor.ts index 9f36c88c986..fca7b8a90fb 100644 --- a/public/app/plugins/panel/table/editor.ts +++ b/public/app/plugins/panel/table/editor.ts @@ -21,10 +21,12 @@ export class TablePanelEditorCtrl { addColumnSegment: any; unitFormats: any; getColumnNames: any; + activeStyleIndex: number; /** @ngInject */ constructor($scope, private $q, private uiSegmentSrv) { $scope.editor = this; + this.activeStyleIndex = 0; this.panelCtrl = $scope.ctrl; this.panel = this.panelCtrl.panel; this.transformers = transformers; @@ -111,12 +113,13 @@ export class TablePanelEditorCtrl { decimals: 2, colors: ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"], colorMode: null, - pattern: '/.*/', + pattern: '', dateFormat: 'YYYY-MM-DD HH:mm:ss', thresholds: [], }; this.panel.styles.push(angular.copy(columnStyleDefaults)); + this.activeStyleIndex = this.panel.styles.length-1; } removeColumnStyle(style) { diff --git a/public/sass/components/_tabs.scss b/public/sass/components/_tabs.scss index 2426f70afee..32e395c4d73 100644 --- a/public/sass/components/_tabs.scss +++ b/public/sass/components/_tabs.scss @@ -68,3 +68,12 @@ top: 1px; } } + +.form-tabs-wrapper { + @include brand-bottom-border(); + @include clearfix(); +} + +.form-tabs-content { + padding: $spacer*2 $spacer; +} From be284adaccaafb8dcc07dd5ce7278c354c7c6f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 15:26:05 +0200 Subject: [PATCH 09/16] table: more table options refactoring --- public/app/plugins/panel/table/editor.html | 117 ++++++++++----------- public/app/plugins/panel/table/editor.ts | 18 +++- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 657771d8338..5697bebe97d 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -53,7 +53,7 @@
- Style Rules + Column Style Rules @@ -69,90 +69,81 @@
-
+
+
Options
-
- -
- -
-
- +
-
-
Date options
+
+
Type
+
+ +
+ +
+
+
-
-
-
String options
- -
- -
- -
-
Number options
- -
-
- -
-
-
-
-
- - -
-
+
+
-
-
Thresholds & Coloring
-
-
- - -
-
- -
- -
-
- -
- - - - - - - - - - -
- Invert -
-
+
+
+ +
+
+
+ +
+
+
Thresholds
+
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + +
+ Invert +
+
+
+ +
+ diff --git a/public/app/plugins/panel/table/editor.ts b/public/app/plugins/panel/table/editor.ts index fca7b8a90fb..9379702e7db 100644 --- a/public/app/plugins/panel/table/editor.ts +++ b/public/app/plugins/panel/table/editor.ts @@ -106,7 +106,7 @@ export class TablePanelEditorCtrl { } addColumnStyle() { - var columnStyleDefaults = { + var newStyleRule = { unit: 'short', type: 'number', alias: '', @@ -118,8 +118,20 @@ export class TablePanelEditorCtrl { thresholds: [], }; - this.panel.styles.push(angular.copy(columnStyleDefaults)); - this.activeStyleIndex = this.panel.styles.length-1; + var styles = this.panel.styles; + var stylesCount = styles.length; + var indexToInsert = stylesCount; + + // check if last is a catch all rule, then add it before that one + if (stylesCount > 0) { + var last = styles[stylesCount-1]; + if (last.pattern === '/.*/') { + indexToInsert = stylesCount-1; + } + } + + styles.splice(indexToInsert, 0, newStyleRule); + this.activeStyleIndex = indexToInsert; } removeColumnStyle(style) { From f168c9e53dd3a37dfbd757878f42ad655960250f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 15:57:15 +0200 Subject: [PATCH 10/16] table: minor ux options update --- public/app/plugins/panel/table/editor.html | 172 ++++++++++----------- 1 file changed, 85 insertions(+), 87 deletions(-) diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 5697bebe97d..7eae11d7b0a 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -29,108 +29,106 @@
Table Display
-
-
- - -
- -
- -
- -
-
-
-
+
+ + +
+ +
+ +
+ +
+
+
- Column Style Rules - + Column Style Rules +
-
-
Options
-
-
- - -
-
-
- - -
-
+
+
Options
+
+
+ + +
+
+
+ + +
+
-
-
Type
+
+
Type
-
- -
- -
-
-
- - -
+
+ +
+ +
+
+
+ + +
-
- -
+
+ +
-
-
- -
-
-
- - -
-
-
+
+
+ +
+
+
+ + +
+
+
-
-
Thresholds
-
- - -
-
- -
- -
-
-
- - - - - +
+
Thresholds
+
+ + +
+
+ +
+ +
+
+
+ + + + + From 25a267a7ab3d7db71724cbf5f5b9b369425c1c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 May 2017 16:08:53 +0200 Subject: [PATCH 11/16] fix: segment used influxdb naming for variable in options callback, should be more generic --- public/app/core/directives/metric_segment.js | 2 +- .../app/plugins/datasource/influxdb/partials/query.editor.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/core/directives/metric_segment.js b/public/app/core/directives/metric_segment.js index c3e51dc7a0c..2e9442c15a0 100644 --- a/public/app/core/directives/metric_segment.js +++ b/public/app/core/directives/metric_segment.js @@ -77,7 +77,7 @@ function (_, $, coreModule) { $scope.source = function(query, callback) { $scope.$apply(function() { - $scope.getOptions({ measurementFilter: query }).then(function(altSegments) { + $scope.getOptions({ $query: query }).then(function(altSegments) { $scope.altSegments = altSegments; options = _.map($scope.altSegments, function(alt) { return alt.value; }); diff --git a/public/app/plugins/datasource/influxdb/partials/query.editor.html b/public/app/plugins/datasource/influxdb/partials/query.editor.html index bff03fbb7d5..31bc7e6d8ad 100644 --- a/public/app/plugins/datasource/influxdb/partials/query.editor.html +++ b/public/app/plugins/datasource/influxdb/partials/query.editor.html @@ -11,7 +11,7 @@ - +
From fdc97010b4293a6bb09519378ac4f76d53d1b56a Mon Sep 17 00:00:00 2001 From: Anton Yackushev Date: Tue, 9 May 2017 08:16:48 +0300 Subject: [PATCH 12/16] Rename fielddata_fields to docvalue_fields (#8317) The parameter fielddata_fields is deprecated and removed in 5.0 https://github.com/elastic/elasticsearch/issues/19027 --- public/app/plugins/datasource/elasticsearch/query_builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/elasticsearch/query_builder.js b/public/app/plugins/datasource/elasticsearch/query_builder.js index fbbd4f7e929..dd296c00a34 100644 --- a/public/app/plugins/datasource/elasticsearch/query_builder.js +++ b/public/app/plugins/datasource/elasticsearch/query_builder.js @@ -119,7 +119,7 @@ function (queryDef) { } query.script_fields = {}, - query.fielddata_fields = [this.timeField]; + query.docvalue_fields = [this.timeField]; return query; }; From 8d072de556a0fa7db279b32b778074d2f9c3ce3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 9 May 2017 08:33:37 +0200 Subject: [PATCH 13/16] elasticsearch: changed default terms min_doc_count to 1 and order by to desc, closes #8231 --- public/app/plugins/datasource/elasticsearch/bucket_agg.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/elasticsearch/bucket_agg.js b/public/app/plugins/datasource/elasticsearch/bucket_agg.js index d6d641c1655..b2cfc819579 100644 --- a/public/app/plugins/datasource/elasticsearch/bucket_agg.js +++ b/public/app/plugins/datasource/elasticsearch/bucket_agg.js @@ -81,9 +81,9 @@ function (angular, _, queryDef) { switch($scope.agg.type) { case 'terms': { - settings.order = settings.order || "asc"; + settings.order = settings.order || "desc"; settings.size = settings.size || "10"; - settings.min_doc_count = settings.min_doc_count || 0; + settings.min_doc_count = settings.min_doc_count || 1; settings.orderBy = settings.orderBy || "_term"; if (settings.size !== '0') { From 84141eb14ae0e0d7394c7b41736243b1e4059836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 9 May 2017 08:45:47 +0200 Subject: [PATCH 14/16] docs: updated changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30bcc05597a..022684f9fbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ * **Prometheus**: Support table response formats (column per label) [#6140](https://github.com/grafana/grafana/issues/6140), thx [@mtanda](https://github.com/mtanda) * **Single Stat Panel**: support for non time series data [#6564](https://github.com/grafana/grafana/issues/6564) - ## Minor Enchancements * **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778) @@ -22,12 +21,16 @@ * **Templating**: Data source variable now supports multi value and panel repeats [#7030](https://github.com/grafana/grafana/issues/7030) thx [@mtanda](https://github.com/mtanda) * **Telegram**: Telegram alert is not sending metric and legend. [#8110](https://github.com/grafana/grafana/issues/8110), thx [@bashgeek](https://github.com/bashgeek) * **Graph**: Support dashed lines [#514](https://github.com/grafana/grafana/issues/514), thx [@smalik03](https://github.com/smalik03) +* **Table**: Support to change column header text [#3551](https://github.com/grafana/grafana/issues/3551) ## Fixes * **Table Panel**: Fixed annotation display in table panel, [#8023](https://github.com/grafana/grafana/issues/8023) * **Dashboard**: If refresh is blocked due to tab not visible, then refresh when it becomes visible [#8076](https://github.com/grafana/grafana/issues/8076) thanks [@SimenB](https://github.com/SimenB) * **Snapshots**: Fixed problem with annotations & snapshots [#7659](https://github.com/grafana/grafana/issues/7659) +## Changes +* **Elasticsearch**: Changed elasticsearch Terms aggregation to default to Min Doc Count to 1, and sort order to Top [#8321](https://github.com/grafana/grafana/issues/8321) + # 4.2.0 (2017-03-22) ## Minor Enhancements * **Templates**: Prevent use of the prefix `__` for templates in web UI [#7678](https://github.com/grafana/grafana/issues/7678) From e218052a904b5eaa27d9b486adc03e502984e845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 9 May 2017 12:07:06 +0200 Subject: [PATCH 15/16] fix: fixed slow down issue in table panel by removing the fillter null values feature (#7602), not sure the filter null values is a good table option, should be done in metric query, fixes #8234 --- public/app/plugins/panel/table/editor.html | 4 ---- public/app/plugins/panel/table/module.ts | 1 - public/app/plugins/panel/table/transformers.ts | 12 ++---------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 7eae11d7b0a..77860266b45 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -21,10 +21,6 @@
-
diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index 9b563ca5b18..06475caa332 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -45,7 +45,6 @@ class TablePanelCtrl extends MetricsPanelCtrl { scroll: true, fontSize: '100%', sort: {col: 0, desc: true}, - filterNull: false, }; /** @ngInject */ diff --git a/public/app/plugins/panel/table/transformers.ts b/public/app/plugins/panel/table/transformers.ts index 0f793fa0434..c7f957e0156 100644 --- a/public/app/plugins/panel/table/transformers.ts +++ b/public/app/plugins/panel/table/transformers.ts @@ -220,8 +220,7 @@ transformers['json'] = { }; function transformDataToTable(data, panel) { - var model = new TableModel(), - copyData = angular.copy(data); + var model = new TableModel(); if (!data || data.length === 0) { return model; @@ -232,14 +231,7 @@ function transformDataToTable(data, panel) { throw {message: 'Transformer ' + panel.transform + ' not found'}; } - if (panel.filterNull) { - for (var i = 0; i < copyData.length; i++) { - copyData[i].datapoints = copyData[i].datapoints.filter((dp) => dp[0] != null); - } - } - - transformer.transform(copyData, panel, model); - + transformer.transform(data, panel, model); return model; } From 8bbff2c44eb998e513e5264b2d368c558590c1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 9 May 2017 12:35:44 +0200 Subject: [PATCH 16/16] table: refactoring table options, now column styles are in a seperate tab --- .../plugins/panel/table/column_options.html | 99 +++++++++++++++ .../app/plugins/panel/table/column_options.ts | 120 ++++++++++++++++++ public/app/plugins/panel/table/editor.html | 101 +-------------- public/app/plugins/panel/table/editor.ts | 81 ------------ public/app/plugins/panel/table/module.ts | 2 + public/sass/components/edit_sidemenu.scss | 3 +- 6 files changed, 224 insertions(+), 182 deletions(-) create mode 100644 public/app/plugins/panel/table/column_options.html create mode 100644 public/app/plugins/panel/table/column_options.ts diff --git a/public/app/plugins/panel/table/column_options.html b/public/app/plugins/panel/table/column_options.html new file mode 100644 index 00000000000..35fa4ac2d8b --- /dev/null +++ b/public/app/plugins/panel/table/column_options.html @@ -0,0 +1,99 @@ + +
+ + +
+ +
+
Options
+
+
+ + +
+
+
+ + +
+
+ +
+
Type
+ +
+ +
+ +
+
+
+ + +
+ +
+ +
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
Thresholds
+
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + +
+ Invert +
+
+
+ +
+ + +
+
+ +
diff --git a/public/app/plugins/panel/table/column_options.ts b/public/app/plugins/panel/table/column_options.ts new file mode 100644 index 00000000000..5109f87f86d --- /dev/null +++ b/public/app/plugins/panel/table/column_options.ts @@ -0,0 +1,120 @@ +/// + + +import _ from 'lodash'; +import $ from 'jquery'; +import moment from 'moment'; +import angular from 'angular'; + +import kbn from 'app/core/utils/kbn'; + +export class ColumnOptionsCtrl { + panel: any; + panelCtrl: any; + colorModes: any; + columnStyles: any; + columnTypes: any; + fontSizes: any; + dateFormats: any; + addColumnSegment: any; + unitFormats: any; + getColumnNames: any; + activeStyleIndex: number; + + /** @ngInject */ + constructor($scope, private $q, private uiSegmentSrv) { + $scope.editor = this; + this.activeStyleIndex = 0; + this.panelCtrl = $scope.ctrl; + this.panel = this.panelCtrl.panel; + this.unitFormats = kbn.getUnitFormats(); + this.colorModes = [ + {text: 'Disabled', value: null}, + {text: 'Cell', value: 'cell'}, + {text: 'Value', value: 'value'}, + {text: 'Row', value: 'row'}, + ]; + this.columnTypes = [ + {text: 'Number', value: 'number'}, + {text: 'String', value: 'string'}, + {text: 'Date', value: 'date'}, + {text: 'Hidden', value: 'hidden'} + ]; + this.fontSizes = ['80%', '90%', '100%', '110%', '120%', '130%', '150%', '160%', '180%', '200%', '220%', '250%']; + this.dateFormats = [ + {text: 'YYYY-MM-DD HH:mm:ss', value: 'YYYY-MM-DD HH:mm:ss'}, + {text: 'MM/DD/YY h:mm:ss a', value: 'MM/DD/YY h:mm:ss a'}, + {text: 'MMMM D, YYYY LT', value: 'MMMM D, YYYY LT'}, + ]; + + this.getColumnNames = () => { + if (!this.panelCtrl.table) { + return []; + } + return _.map(this.panelCtrl.table.columns, function(col: any) { + return col.text; + }); + }; + } + + render() { + this.panelCtrl.render(); + } + + setUnitFormat(column, subItem) { + column.unit = subItem.value; + this.panelCtrl.render(); + } + + addColumnStyle() { + var newStyleRule = { + 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: '', + dateFormat: 'YYYY-MM-DD HH:mm:ss', + thresholds: [], + }; + + var styles = this.panel.styles; + var stylesCount = styles.length; + var indexToInsert = stylesCount; + + // check if last is a catch all rule, then add it before that one + if (stylesCount > 0) { + var last = styles[stylesCount-1]; + if (last.pattern === '/.*/') { + indexToInsert = stylesCount-1; + } + } + + styles.splice(indexToInsert, 0, newStyleRule); + this.activeStyleIndex = indexToInsert; + } + + removeColumnStyle(style) { + this.panel.styles = _.without(this.panel.styles, style); + } + + invertColorOrder(index) { + var ref = this.panel.styles[index].colors; + var copy = ref[0]; + ref[0] = ref[2]; + ref[2] = copy; + this.panelCtrl.render(); + } +} + +/** @ngInject */ +export function columnOptionsTab($q, uiSegmentSrv) { + 'use strict'; + return { + restrict: 'E', + scope: true, + templateUrl: 'public/app/plugins/panel/table/column_options.html', + controller: ColumnOptionsCtrl, + }; +} diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 77860266b45..9854ac26dc3 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -24,7 +24,7 @@
-
Table Display
+
Paging
- -
- Column Style Rules - -
- - - -
- -
-
Options
-
-
- - -
-
-
- - -
-
- -
-
Type
- -
- -
- -
-
-
- - -
- -
- -
- -
-
- -
-
-
- - -
-
-
- -
-
Thresholds
-
- - -
-
- -
- -
-
-
- - - - - - - - - - -
- Invert -
-
-
- -
- - -
-
-
diff --git a/public/app/plugins/panel/table/editor.ts b/public/app/plugins/panel/table/editor.ts index 9379702e7db..ce5d0c1c828 100644 --- a/public/app/plugins/panel/table/editor.ts +++ b/public/app/plugins/panel/table/editor.ts @@ -13,54 +13,19 @@ export class TablePanelEditorCtrl { panel: any; panelCtrl: any; transformers: any; - colorModes: any; - columnStyles: any; - columnTypes: any; fontSizes: any; - dateFormats: any; addColumnSegment: any; - unitFormats: any; getColumnNames: any; - activeStyleIndex: number; /** @ngInject */ constructor($scope, private $q, private uiSegmentSrv) { $scope.editor = this; - this.activeStyleIndex = 0; this.panelCtrl = $scope.ctrl; this.panel = this.panelCtrl.panel; this.transformers = transformers; - this.unitFormats = kbn.getUnitFormats(); - this.colorModes = [ - {text: 'Disabled', value: null}, - {text: 'Cell', value: 'cell'}, - {text: 'Value', value: 'value'}, - {text: 'Row', value: 'row'}, - ]; - this.columnTypes = [ - {text: 'Number', value: 'number'}, - {text: 'String', value: 'string'}, - {text: 'Date', value: 'date'}, - {text: 'Hidden', value: 'hidden'} - ]; this.fontSizes = ['80%', '90%', '100%', '110%', '120%', '130%', '150%', '160%', '180%', '200%', '220%', '250%']; - this.dateFormats = [ - {text: 'YYYY-MM-DD HH:mm:ss', value: 'YYYY-MM-DD HH:mm:ss'}, - {text: 'MM/DD/YY h:mm:ss a', value: 'MM/DD/YY h:mm:ss a'}, - {text: 'MMMM D, YYYY LT', value: 'MMMM D, YYYY LT'}, - ]; this.addColumnSegment = uiSegmentSrv.newPlusButton(); - - // this is used from bs-typeahead and needs to be instance bound - this.getColumnNames = () => { - if (!this.panelCtrl.table) { - return []; - } - return _.map(this.panelCtrl.table.columns, function(col: any) { - return col.text; - }); - }; } getColumnOptions() { @@ -99,52 +64,6 @@ export class TablePanelEditorCtrl { this.panel.columns = _.without(this.panel.columns, column); this.panelCtrl.render(); } - - setUnitFormat(column, subItem) { - column.unit = subItem.value; - this.panelCtrl.render(); - } - - addColumnStyle() { - var newStyleRule = { - 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: '', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - thresholds: [], - }; - - var styles = this.panel.styles; - var stylesCount = styles.length; - var indexToInsert = stylesCount; - - // check if last is a catch all rule, then add it before that one - if (stylesCount > 0) { - var last = styles[stylesCount-1]; - if (last.pattern === '/.*/') { - indexToInsert = stylesCount-1; - } - } - - styles.splice(indexToInsert, 0, newStyleRule); - this.activeStyleIndex = indexToInsert; - } - - removeColumnStyle(style) { - this.panel.styles = _.without(this.panel.styles, style); - } - - invertColorOrder(index) { - var ref = this.panel.styles[index].colors; - var copy = ref[0]; - ref[0] = ref[2]; - ref[2] = copy; - this.panelCtrl.render(); - } } /** @ngInject */ diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index 06475caa332..8acf14f56ca 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -8,6 +8,7 @@ import * as FileExport from 'app/core/utils/file_export'; 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 { @@ -70,6 +71,7 @@ class TablePanelCtrl extends MetricsPanelCtrl { onInitEditMode() { this.addEditorTab('Options', tablePanelEditor, 2); + this.addEditorTab('Column Styles', columnOptionsTab, 3); } onInitPanelActions(actions) { diff --git a/public/sass/components/edit_sidemenu.scss b/public/sass/components/edit_sidemenu.scss index 83f845c08e1..d7844ab6f36 100644 --- a/public/sass/components/edit_sidemenu.scss +++ b/public/sass/components/edit_sidemenu.scss @@ -10,7 +10,8 @@ } .edit-sidemenu-aside { - min-width: 15rem; + min-width: 6rem; + margin-right: $spacer*2; } .edit-sidemenu {