Commit 2435ca5d0ff0dfd6e362de658311b00b853f759a

Authored by Andrew Shvayka
2 parents 10d39d20 34c6c30e

Merge remote-tracking branch 'origin/master' into asset-alarm-mgmt

@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <modelVersion>4.0.0</modelVersion> 22 <modelVersion>4.0.0</modelVersion>
23 <parent> 23 <parent>
24 <groupId>org.thingsboard</groupId> 24 <groupId>org.thingsboard</groupId>
25 - <version>1.2.3</version> 25 + <version>1.3.0-SNAPSHOT</version>
26 <artifactId>extensions</artifactId> 26 <artifactId>extensions</artifactId>
27 </parent> 27 </parent>
28 <groupId>org.thingsboard.extensions</groupId> 28 <groupId>org.thingsboard.extensions</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>extensions</artifactId> 24 <artifactId>extensions</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.extensions</groupId> 26 <groupId>org.thingsboard.extensions</groupId>
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <modelVersion>4.0.0</modelVersion> 22 <modelVersion>4.0.0</modelVersion>
23 <parent> 23 <parent>
24 <groupId>org.thingsboard</groupId> 24 <groupId>org.thingsboard</groupId>
25 - <version>1.2.3</version> 25 + <version>1.3.0-SNAPSHOT</version>
26 <artifactId>extensions</artifactId> 26 <artifactId>extensions</artifactId>
27 </parent> 27 </parent>
28 <groupId>org.thingsboard.extensions</groupId> 28 <groupId>org.thingsboard.extensions</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <groupId>org.thingsboard</groupId> 21 <groupId>org.thingsboard</groupId>
22 <artifactId>thingsboard</artifactId> 22 <artifactId>thingsboard</artifactId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <packaging>pom</packaging> 24 <packaging>pom</packaging>
25 25
26 <name>Thingsboard</name> 26 <name>Thingsboard</name>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
1 { 1 {
2 "name": "thingsboard", 2 "name": "thingsboard",
3 "private": true, 3 "private": true,
4 - "version": "1.2.3", 4 + "version": "1.3.0",
5 "description": "Thingsboard UI", 5 "description": "Thingsboard UI",
6 "licenses": [ 6 "licenses": [
7 { 7 {
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>1.2.3</version> 23 + <version>1.3.0-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -126,6 +126,7 @@ export default class Subscription { @@ -126,6 +126,7 @@ export default class Subscription {
126 dataKey: dataKey, 126 dataKey: dataKey,
127 dataIndex: dataIndex++ 127 dataIndex: dataIndex++
128 }; 128 };
  129 + legendKey.dataKey.hidden = false;
129 this.legendData.keys.push(legendKey); 130 this.legendData.keys.push(legendKey);
130 var legendKeyData = { 131 var legendKeyData = {
131 min: null, 132 min: null,
@@ -146,11 +147,11 @@ export default class Subscription { @@ -146,11 +147,11 @@ export default class Subscription {
146 this.legendData.keys = this.ctx.$filter('orderBy')(this.legendData.keys, '+label'); 147 this.legendData.keys = this.ctx.$filter('orderBy')(this.legendData.keys, '+label');
147 registration = this.ctx.$scope.$watch( 148 registration = this.ctx.$scope.$watch(
148 function() { 149 function() {
149 - return subscription.legendData.data; 150 + return subscription.legendData.keys;
150 }, 151 },
151 function (newValue, oldValue) { 152 function (newValue, oldValue) {
152 for(var i = 0; i < newValue.length; i++) { 153 for(var i = 0; i < newValue.length; i++) {
153 - if(newValue[i].hidden != oldValue[i].hidden) { 154 + if(newValue[i].dataKey.hidden != oldValue[i].dataKey.hidden) {
154 subscription.updateDataVisibility(i); 155 subscription.updateDataVisibility(i);
155 } 156 }
156 } 157 }
@@ -307,7 +308,7 @@ export default class Subscription { @@ -307,7 +308,7 @@ export default class Subscription {
307 } 308 }
308 309
309 updateDataVisibility(index) { 310 updateDataVisibility(index) {
310 - var hidden = this.legendData.data[index].hidden; 311 + var hidden = this.legendData.keys[index].dataKey.hidden;
311 if (hidden) { 312 if (hidden) {
312 this.hiddenData[index].data = this.data[index].data; 313 this.hiddenData[index].data = this.data[index].data;
313 this.data[index].data = []; 314 this.data[index].data = [];
@@ -418,7 +419,7 @@ export default class Subscription { @@ -418,7 +419,7 @@ export default class Subscription {
418 this.notifyDataLoaded(); 419 this.notifyDataLoaded();
419 var update = true; 420 var update = true;
420 var currentData; 421 var currentData;
421 - if (this.displayLegend && this.legendData.data[datasourceIndex + dataKeyIndex].hidden) { 422 + if (this.displayLegend && this.legendData.keys[datasourceIndex + dataKeyIndex].dataKey.hidden) {
422 currentData = this.hiddenData[datasourceIndex + dataKeyIndex]; 423 currentData = this.hiddenData[datasourceIndex + dataKeyIndex];
423 } else { 424 } else {
424 currentData = this.data[datasourceIndex + dataKeyIndex]; 425 currentData = this.data[datasourceIndex + dataKeyIndex];
@@ -445,18 +446,21 @@ export default class Subscription { @@ -445,18 +446,21 @@ export default class Subscription {
445 } 446 }
446 447
447 updateLegend(dataIndex, data, apply) { 448 updateLegend(dataIndex, data, apply) {
  449 + var dataKey = this.legendData.keys[dataIndex].dataKey;
  450 + var decimals = angular.isDefined(dataKey.decimals) ? dataKey.decimals : this.decimals;
  451 + var units = dataKey.units && dataKey.units.length ? dataKey.units : this.units;
448 var legendKeyData = this.legendData.data[dataIndex]; 452 var legendKeyData = this.legendData.data[dataIndex];
449 if (this.legendConfig.showMin) { 453 if (this.legendConfig.showMin) {
450 - legendKeyData.min = this.ctx.widgetUtils.formatValue(calculateMin(data), this.decimals, this.units); 454 + legendKeyData.min = this.ctx.widgetUtils.formatValue(calculateMin(data), decimals, units);
451 } 455 }
452 if (this.legendConfig.showMax) { 456 if (this.legendConfig.showMax) {
453 - legendKeyData.max = this.ctx.widgetUtils.formatValue(calculateMax(data), this.decimals, this.units); 457 + legendKeyData.max = this.ctx.widgetUtils.formatValue(calculateMax(data), decimals, units);
454 } 458 }
455 if (this.legendConfig.showAvg) { 459 if (this.legendConfig.showAvg) {
456 - legendKeyData.avg = this.ctx.widgetUtils.formatValue(calculateAvg(data), this.decimals, this.units); 460 + legendKeyData.avg = this.ctx.widgetUtils.formatValue(calculateAvg(data), decimals, units);
457 } 461 }
458 if (this.legendConfig.showTotal) { 462 if (this.legendConfig.showTotal) {
459 - legendKeyData.total = this.ctx.widgetUtils.formatValue(calculateTotal(data), this.decimals, this.units); 463 + legendKeyData.total = this.ctx.widgetUtils.formatValue(calculateTotal(data), decimals, units);
460 } 464 }
461 this.callbacks.legendDataUpdated(this, apply !== false); 465 this.callbacks.legendDataUpdated(this, apply !== false);
462 } 466 }
@@ -76,6 +76,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) { @@ -76,6 +76,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) {
76 scope.model.name = ngModelCtrl.$viewValue.name; 76 scope.model.name = ngModelCtrl.$viewValue.name;
77 scope.model.label = ngModelCtrl.$viewValue.label; 77 scope.model.label = ngModelCtrl.$viewValue.label;
78 scope.model.color = ngModelCtrl.$viewValue.color; 78 scope.model.color = ngModelCtrl.$viewValue.color;
  79 + scope.model.units = ngModelCtrl.$viewValue.units;
  80 + scope.model.decimals = ngModelCtrl.$viewValue.decimals;
79 scope.model.funcBody = ngModelCtrl.$viewValue.funcBody; 81 scope.model.funcBody = ngModelCtrl.$viewValue.funcBody;
80 scope.model.postFuncBody = ngModelCtrl.$viewValue.postFuncBody; 82 scope.model.postFuncBody = ngModelCtrl.$viewValue.postFuncBody;
81 scope.model.usePostProcessing = scope.model.postFuncBody ? true : false; 83 scope.model.usePostProcessing = scope.model.postFuncBody ? true : false;
@@ -97,6 +99,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) { @@ -97,6 +99,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) {
97 value.name = scope.model.name; 99 value.name = scope.model.name;
98 value.label = scope.model.label; 100 value.label = scope.model.label;
99 value.color = scope.model.color; 101 value.color = scope.model.color;
  102 + value.units = scope.model.units;
  103 + value.decimals = scope.model.decimals;
100 value.funcBody = scope.model.funcBody; 104 value.funcBody = scope.model.funcBody;
101 if (!scope.model.postFuncBody) { 105 if (!scope.model.postFuncBody) {
102 delete value.postFuncBody; 106 delete value.postFuncBody;
@@ -48,6 +48,16 @@ @@ -48,6 +48,16 @@
48 md-color-history="false"> 48 md-color-history="false">
49 </div> 49 </div>
50 </div> 50 </div>
  51 + <div layout="row" layout-align="start center">
  52 + <md-input-container flex>
  53 + <label translate>datakey.units</label>
  54 + <input name="units" ng-model="model.units">
  55 + </md-input-container>
  56 + <md-input-container flex>
  57 + <label translate>datakey.decimals</label>
  58 + <input name="decimals" ng-model="model.decimals" type="number" min="0" max="15" step="1" ng-pattern="/^\d*$/">
  59 + </md-input-container>
  60 + </div>
51 <section layout="column" ng-if="model.type === types.dataKeyType.function"> 61 <section layout="column" ng-if="model.type === types.dataKeyType.function">
52 <span translate>datakey.data-generation-func</span> 62 <span translate>datakey.data-generation-func</span>
53 <br/> 63 <br/>
@@ -45,7 +45,7 @@ function Legend($compile, $templateCache, types) { @@ -45,7 +45,7 @@ function Legend($compile, $templateCache, types) {
45 scope.legendConfig.position === types.position.top.value; 45 scope.legendConfig.position === types.position.top.value;
46 46
47 scope.toggleHideData = function(index) { 47 scope.toggleHideData = function(index) {
48 - scope.legendData.data[index].hidden = !scope.legendData.data[index].hidden; 48 + scope.legendData.keys[index].dataKey.hidden = !scope.legendData.keys[index].dataKey.hidden;
49 } 49 }
50 50
51 $compile(element.contents())(scope); 51 $compile(element.contents())(scope);
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 <td><span class="tb-legend-line" ng-style="{backgroundColor: legendKey.dataKey.color}"></span></td> 30 <td><span class="tb-legend-line" ng-style="{backgroundColor: legendKey.dataKey.color}"></span></td>
31 <td class="tb-legend-label" 31 <td class="tb-legend-label"
32 ng-click="toggleHideData(legendKey.dataIndex)" 32 ng-click="toggleHideData(legendKey.dataIndex)"
33 - ng-class="{ 'tb-hidden-label': legendData.data[legendKey.dataIndex].hidden, 'tb-horizontal': isHorizontal }"> 33 + ng-class="{ 'tb-hidden-label': legendData.keys[legendKey.dataIndex].dataKey.hidden, 'tb-horizontal': isHorizontal }">
34 {{ legendKey.dataKey.label }} 34 {{ legendKey.dataKey.label }}
35 </td> 35 </td>
36 <td class="tb-legend-value" ng-if="legendConfig.showMin === true">{{ legendData.data[legendKey.dataIndex].min }}</td> 36 <td class="tb-legend-value" ng-if="legendConfig.showMin === true">{{ legendData.data[legendKey.dataIndex].min }}</td>
@@ -355,10 +355,10 @@ function WidgetConfig($compile, $templateCache, $rootScope, $timeout, types, uti @@ -355,10 +355,10 @@ function WidgetConfig($compile, $templateCache, $rootScope, $timeout, types, uti
355 var matches = false; 355 var matches = false;
356 do { 356 do {
357 matches = false; 357 matches = false;
358 - if (value.datasources) {  
359 - for (var d in value.datasources) {  
360 - var datasource = value.datasources[d];  
361 - for (var k in datasource.dataKeys) { 358 + if (value.config.datasources) {
  359 + for (var d=0;d<value.config.datasources.length;d++) {
  360 + var datasource = value.config.datasources[d];
  361 + for (var k=0;k<datasource.dataKeys.length;k++) {
362 var dataKey = datasource.dataKeys[k]; 362 var dataKey = datasource.dataKeys[k];
363 if (dataKey.label === label) { 363 if (dataKey.label === label) {
364 i++; 364 i++;
@@ -375,9 +375,9 @@ function WidgetConfig($compile, $templateCache, $rootScope, $timeout, types, uti @@ -375,9 +375,9 @@ function WidgetConfig($compile, $templateCache, $rootScope, $timeout, types, uti
375 scope.genNextColor = function () { 375 scope.genNextColor = function () {
376 var i = 0; 376 var i = 0;
377 var value = ngModelCtrl.$viewValue; 377 var value = ngModelCtrl.$viewValue;
378 - if (value.datasources) {  
379 - for (var d in value.datasources) {  
380 - var datasource = value.datasources[d]; 378 + if (value.config.datasources) {
  379 + for (var d=0;d<value.config.datasources.length;d++) {
  380 + var datasource = value.config.datasources[d];
381 i += datasource.dataKeys.length; 381 i += datasource.dataKeys.length;
382 } 382 }
383 } 383 }
@@ -983,8 +983,11 @@ export default function DashboardController(types, dashboardUtils, widgetService @@ -983,8 +983,11 @@ export default function DashboardController(types, dashboardUtils, widgetService
983 if (revert) { 983 if (revert) {
984 vm.dashboard = vm.prevDashboard; 984 vm.dashboard = vm.prevDashboard;
985 vm.dashboardConfiguration = vm.dashboard.configuration; 985 vm.dashboardConfiguration = vm.dashboard.configuration;
  986 + vm.dashboardCtx.dashboardTimewindow = vm.dashboardConfiguration.timewindow;
986 openDashboardState(vm.prevDashboardState); 987 openDashboardState(vm.prevDashboardState);
987 entityAliasesUpdated(); 988 entityAliasesUpdated();
  989 + } else {
  990 + vm.dashboard.configuration.timewindow = vm.dashboardCtx.dashboardTimewindow;
988 } 991 }
989 } 992 }
990 } 993 }
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 is-toolbar 63 is-toolbar
64 direction="left" 64 direction="left"
65 tooltip-direction="bottom" aggregation 65 tooltip-direction="bottom" aggregation
66 - ng-model="vm.dashboardConfiguration.timewindow"> 66 + ng-model="vm.dashboardCtx.dashboardTimewindow">
67 </tb-timewindow> 67 </tb-timewindow>
68 <tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()" 68 <tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()"
69 tooltip-direction="bottom" 69 tooltip-direction="bottom"
@@ -385,6 +385,8 @@ export default angular.module('thingsboard.locale', []) @@ -385,6 +385,8 @@ export default angular.module('thingsboard.locale', [])
385 "advanced": "Advanced", 385 "advanced": "Advanced",
386 "label": "Label", 386 "label": "Label",
387 "color": "Color", 387 "color": "Color",
  388 + "units": "Special symbol to show next to value",
  389 + "decimals": "Number of digits after floating point",
388 "data-generation-func": "Data generation function", 390 "data-generation-func": "Data generation function",
389 "use-data-post-processing-func": "Use data post-processing function", 391 "use-data-post-processing-func": "Use data post-processing function",
390 "configuration": "Data key configuration", 392 "configuration": "Data key configuration",
@@ -41,8 +41,7 @@ export default class TbAnalogueLinearGauge { @@ -41,8 +41,7 @@ export default class TbAnalogueLinearGauge {
41 41
42 var valueInt = settings.valueInt || 3; 42 var valueInt = settings.valueInt || 3;
43 43
44 - var valueDec = (angular.isDefined(settings.valueDec) && settings.valueDec !== null)  
45 - ? settings.valueDec : ctx.decimals; 44 + var valueDec = getValueDec(settings);
46 45
47 step = parseFloat(parseFloat(step).toFixed(valueDec)); 46 step = parseFloat(parseFloat(step).toFixed(valueDec));
48 47
@@ -74,6 +73,32 @@ export default class TbAnalogueLinearGauge { @@ -74,6 +73,32 @@ export default class TbAnalogueLinearGauge {
74 var progressColorStart = tinycolor(keyColor).setAlpha(0.05).toRgbString(); 73 var progressColorStart = tinycolor(keyColor).setAlpha(0.05).toRgbString();
75 var progressColorEnd = tinycolor(keyColor).darken().toRgbString(); 74 var progressColorEnd = tinycolor(keyColor).darken().toRgbString();
76 75
  76 + function getUnits(settings) {
  77 + var dataKey;
  78 + if (ctx.data && ctx.data[0]) {
  79 + dataKey = ctx.data[0].dataKey;
  80 + }
  81 + if (dataKey && dataKey.units && dataKey.units.length) {
  82 + return dataKey.units;
  83 + } else {
  84 + return angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units;
  85 + }
  86 + }
  87 +
  88 + function getValueDec(settings) {
  89 + var dataKey;
  90 + if (ctx.data && ctx.data[0]) {
  91 + dataKey = ctx.data[0].dataKey;
  92 + }
  93 + if (dataKey && angular.isDefined(dataKey.decimals)) {
  94 + return dataKey.decimals;
  95 + } else {
  96 + return (angular.isDefined(settings.valueDec) && settings.valueDec !== null)
  97 + ? settings.valueDec : ctx.decimals;
  98 + }
  99 + }
  100 +
  101 +
77 function getFontFamily(fontSettings) { 102 function getFontFamily(fontSettings) {
78 var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto'; 103 var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto';
79 if (family === 'RobotoDraft') { 104 if (family === 'RobotoDraft') {
@@ -92,7 +117,7 @@ export default class TbAnalogueLinearGauge { @@ -92,7 +117,7 @@ export default class TbAnalogueLinearGauge {
92 maxValue: maxValue, 117 maxValue: maxValue,
93 majorTicks: majorTicks, 118 majorTicks: majorTicks,
94 minorTicks: settings.minorTicks || 2, 119 minorTicks: settings.minorTicks || 2,
95 - units: angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units, 120 + units: getUnits(settings),
96 title: ((settings.showUnitTitle !== false) ? 121 title: ((settings.showUnitTitle !== false) ?
97 (settings.unitTitle && settings.unitTitle.length > 0 ? 122 (settings.unitTitle && settings.unitTitle.length > 0 ?
98 settings.unitTitle : dataKey.label) : ''), 123 settings.unitTitle : dataKey.label) : ''),
@@ -42,8 +42,7 @@ export default class TbAnalogueRadialGauge { @@ -42,8 +42,7 @@ export default class TbAnalogueRadialGauge {
42 42
43 var valueInt = settings.valueInt || 3; 43 var valueInt = settings.valueInt || 3;
44 44
45 - var valueDec = (angular.isDefined(settings.valueDec) && settings.valueDec !== null)  
46 - ? settings.valueDec : ctx.decimals; 45 + var valueDec = getValueDec(settings);
47 46
48 step = parseFloat(parseFloat(step).toFixed(valueDec)); 47 step = parseFloat(parseFloat(step).toFixed(valueDec));
49 48
@@ -71,6 +70,31 @@ export default class TbAnalogueRadialGauge { @@ -71,6 +70,31 @@ export default class TbAnalogueRadialGauge {
71 70
72 var colorNumbers = tinycolor(keyColor).darken(20).toRgbString(); 71 var colorNumbers = tinycolor(keyColor).darken(20).toRgbString();
73 72
  73 + function getUnits(settings) {
  74 + var dataKey;
  75 + if (ctx.data && ctx.data[0]) {
  76 + dataKey = ctx.data[0].dataKey;
  77 + }
  78 + if (dataKey && dataKey.units && dataKey.units.length) {
  79 + return dataKey.units;
  80 + } else {
  81 + return angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units;
  82 + }
  83 + }
  84 +
  85 + function getValueDec(settings) {
  86 + var dataKey;
  87 + if (ctx.data && ctx.data[0]) {
  88 + dataKey = ctx.data[0].dataKey;
  89 + }
  90 + if (dataKey && angular.isDefined(dataKey.decimals)) {
  91 + return dataKey.decimals;
  92 + } else {
  93 + return (angular.isDefined(settings.valueDec) && settings.valueDec !== null)
  94 + ? settings.valueDec : ctx.decimals;
  95 + }
  96 + }
  97 +
74 function getFontFamily(fontSettings) { 98 function getFontFamily(fontSettings) {
75 var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto'; 99 var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto';
76 if (family === 'RobotoDraft') { 100 if (family === 'RobotoDraft') {
@@ -89,7 +113,7 @@ export default class TbAnalogueRadialGauge { @@ -89,7 +113,7 @@ export default class TbAnalogueRadialGauge {
89 maxValue: maxValue, 113 maxValue: maxValue,
90 majorTicks: majorTicks, 114 majorTicks: majorTicks,
91 minorTicks: settings.minorTicks || 2, 115 minorTicks: settings.minorTicks || 2,
92 - units: angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units, 116 + units: getUnits(settings),
93 title: ((settings.showUnitTitle !== false) ? 117 title: ((settings.showUnitTitle !== false) ?
94 (settings.unitTitle && settings.unitTitle.length > 0 ? 118 (settings.unitTitle && settings.unitTitle.length > 0 ?
95 settings.unitTitle : dataKey.label) : ''), 119 settings.unitTitle : dataKey.label) : ''),
@@ -54,10 +54,13 @@ export default class TbCanvasDigitalGauge { @@ -54,10 +54,13 @@ export default class TbCanvasDigitalGauge {
54 this.localSettings.levelColors = settings.levelColors.slice(); 54 this.localSettings.levelColors = settings.levelColors.slice();
55 } 55 }
56 56
57 - this.localSettings.decimals = (angular.isDefined(settings.decimals) && settings.decimals !== null)  
58 - ? settings.decimals : ctx.decimals; 57 + this.localSettings.decimals = angular.isDefined(dataKey.decimals) ? dataKey.decimals :
  58 + ((angular.isDefined(settings.decimals) && settings.decimals !== null)
  59 + ? settings.decimals : ctx.decimals);
  60 +
  61 + this.localSettings.units = dataKey.units && dataKey.units.length ? dataKey.units :
  62 + (angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units);
59 63
60 - this.localSettings.units = angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units;  
61 this.localSettings.hideValue = settings.showValue !== true; 64 this.localSettings.hideValue = settings.showValue !== true;
62 this.localSettings.hideMinMax = settings.showMinMax !== true; 65 this.localSettings.hideMinMax = settings.showMinMax !== true;
63 66
@@ -104,8 +104,10 @@ export default class TbFlot { @@ -104,8 +104,10 @@ export default class TbFlot {
104 104
105 if (this.chartType === 'pie') { 105 if (this.chartType === 'pie') {
106 ctx.tooltipFormatter = function(item) { 106 ctx.tooltipFormatter = function(item) {
  107 + var units = item.series.dataKey.units && item.series.dataKey.units.length ? item.series.dataKey.units : tbFlot.ctx.trackUnits;
  108 + var decimals = angular.isDefined(item.series.dataKey.decimals) ? item.series.dataKey.decimals : tbFlot.ctx.trackDecimals;
107 var divElement = seriesInfoDiv(item.series.dataKey.label, item.series.dataKey.color, 109 var divElement = seriesInfoDiv(item.series.dataKey.label, item.series.dataKey.color,
108 - item.datapoint[1][0][1], tbFlot.ctx.trackUnits, tbFlot.ctx.trackDecimals, true, item.series.percent); 110 + item.datapoint[1][0][1], units, decimals, true, item.series.percent);
109 return divElement.prop('outerHTML'); 111 return divElement.prop('outerHTML');
110 }; 112 };
111 } else { 113 } else {
@@ -127,18 +129,19 @@ export default class TbFlot { @@ -127,18 +129,19 @@ export default class TbFlot {
127 if (tbFlot.ctx.tooltipIndividual && seriesHoverInfo.index !== seriesIndex) { 129 if (tbFlot.ctx.tooltipIndividual && seriesHoverInfo.index !== seriesIndex) {
128 continue; 130 continue;
129 } 131 }
  132 + var units = seriesHoverInfo.units && seriesHoverInfo.units.length ? seriesHoverInfo.units : tbFlot.ctx.trackUnits;
  133 + var decimals = angular.isDefined(seriesHoverInfo.decimals) ? seriesHoverInfo.decimals : tbFlot.ctx.trackDecimals;
130 var divElement = seriesInfoDiv(seriesHoverInfo.label, seriesHoverInfo.color, 134 var divElement = seriesInfoDiv(seriesHoverInfo.label, seriesHoverInfo.color,
131 - seriesHoverInfo.value, tbFlot.ctx.trackUnits, tbFlot.ctx.trackDecimals, seriesHoverInfo.index === seriesIndex); 135 + seriesHoverInfo.value, units, decimals, seriesHoverInfo.index === seriesIndex);
132 content += divElement.prop('outerHTML'); 136 content += divElement.prop('outerHTML');
133 } 137 }
134 return content; 138 return content;
135 }; 139 };
136 } 140 }
137 141
138 - ctx.trackDecimals = angular.isDefined(settings.decimals) ?  
139 - settings.decimals : ctx.decimals; 142 + ctx.trackDecimals = ctx.decimals;
140 143
141 - ctx.trackUnits = angular.isDefined(settings.units) ? settings.units : ctx.units; 144 + ctx.trackUnits = ctx.units;
142 145
143 ctx.tooltipIndividual = this.chartType === 'pie' || (angular.isDefined(settings.tooltipIndividual) ? settings.tooltipIndividual : false); 146 ctx.tooltipIndividual = this.chartType === 'pie' || (angular.isDefined(settings.tooltipIndividual) ? settings.tooltipIndividual : false);
144 ctx.tooltipCumulative = angular.isDefined(settings.tooltipCumulative) ? settings.tooltipCumulative : false; 147 ctx.tooltipCumulative = angular.isDefined(settings.tooltipCumulative) ? settings.tooltipCumulative : false;
@@ -172,7 +175,7 @@ export default class TbFlot { @@ -172,7 +175,7 @@ export default class TbFlot {
172 font: angular.copy(font), 175 font: angular.copy(font),
173 labelFont: angular.copy(font) 176 labelFont: angular.copy(font)
174 }; 177 };
175 - options.yaxis = { 178 + this.yaxis = {
176 font: angular.copy(font), 179 font: angular.copy(font),
177 labelFont: angular.copy(font) 180 labelFont: angular.copy(font)
178 }; 181 };
@@ -188,32 +191,33 @@ export default class TbFlot { @@ -188,32 +191,33 @@ export default class TbFlot {
188 options.xaxis.labelFont.size = options.xaxis.font.size+2; 191 options.xaxis.labelFont.size = options.xaxis.font.size+2;
189 options.xaxis.labelFont.weight = "bold"; 192 options.xaxis.labelFont.weight = "bold";
190 } 193 }
191 - if (settings.yaxis) { 194 +
  195 + ctx.yAxisTickFormatter = function(value/*, axis*/) {
192 if (settings.yaxis.showLabels === false) { 196 if (settings.yaxis.showLabels === false) {
193 - options.yaxis.tickFormatter = function() {  
194 - return '';  
195 - };  
196 - } else if (ctx.trackUnits && ctx.trackUnits.length > 0) {  
197 - options.yaxis.tickFormatter = function(value, axis) {  
198 - var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1,  
199 - formatted = "" + Math.round(value * factor) / factor;  
200 - if (axis.tickDecimals != null) {  
201 - var decimal = formatted.indexOf("."),  
202 - precision = decimal === -1 ? 0 : formatted.length - decimal - 1;  
203 -  
204 - if (precision < axis.tickDecimals) {  
205 - formatted = (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);  
206 - }  
207 - }  
208 - formatted += ' ' + tbFlot.ctx.trackUnits;  
209 - return formatted;  
210 - }; 197 + return '';
  198 + }
  199 + var factor = this.tickDecimals ? Math.pow(10, this.tickDecimals) : 1,
  200 + formatted = "" + Math.round(value * factor) / factor;
  201 + if (this.tickDecimals != null) {
  202 + var decimal = formatted.indexOf("."),
  203 + precision = decimal === -1 ? 0 : formatted.length - decimal - 1;
  204 +
  205 + if (precision < this.tickDecimals) {
  206 + formatted = (precision ? formatted : formatted + ".") + ("" + factor).substr(1, this.tickDecimals - precision);
  207 + }
211 } 208 }
212 - options.yaxis.font.color = settings.yaxis.color || options.yaxis.font.color;  
213 - options.yaxis.label = settings.yaxis.title || null;  
214 - options.yaxis.labelFont.color = options.yaxis.font.color;  
215 - options.yaxis.labelFont.size = options.yaxis.font.size+2;  
216 - options.yaxis.labelFont.weight = "bold"; 209 + formatted += ' ' + this.tickUnits;
  210 + return formatted;
  211 + }
  212 +
  213 + this.yaxis.tickFormatter = ctx.yAxisTickFormatter;
  214 +
  215 + if (settings.yaxis) {
  216 + this.yaxis.font.color = settings.yaxis.color || this.yaxis.font.color;
  217 + this.yaxis.label = settings.yaxis.title || null;
  218 + this.yaxis.labelFont.color = this.yaxis.font.color;
  219 + this.yaxis.labelFont.size = this.yaxis.font.size+2;
  220 + this.yaxis.labelFont.weight = "bold";
217 } 221 }
218 222
219 options.grid.borderWidth = 1; 223 options.grid.borderWidth = 1;
@@ -229,7 +233,7 @@ export default class TbFlot { @@ -229,7 +233,7 @@ export default class TbFlot {
229 options.xaxis.tickLength = 0; 233 options.xaxis.tickLength = 0;
230 } 234 }
231 if (settings.grid.horizontalLines === false) { 235 if (settings.grid.horizontalLines === false) {
232 - options.yaxis.tickLength = 0; 236 + this.yaxis.tickLength = 0;
233 } 237 }
234 } 238 }
235 239
@@ -311,6 +315,8 @@ export default class TbFlot { @@ -311,6 +315,8 @@ export default class TbFlot {
311 this.subscription = subscription; 315 this.subscription = subscription;
312 this.$element = $element; 316 this.$element = $element;
313 var colors = []; 317 var colors = [];
  318 + this.yaxes = [];
  319 + var yaxesMap = {};
314 for (var i = 0; i < this.subscription.data.length; i++) { 320 for (var i = 0; i < this.subscription.data.length; i++) {
315 var series = this.subscription.data[i]; 321 var series = this.subscription.data[i];
316 colors.push(series.dataKey.color); 322 colors.push(series.dataKey.color);
@@ -342,8 +348,29 @@ export default class TbFlot { @@ -342,8 +348,29 @@ export default class TbFlot {
342 348
343 series.highlightColor = lineColor.toRgbString(); 349 series.highlightColor = lineColor.toRgbString();
344 350
  351 + if (this.yaxis) {
  352 + var units = series.dataKey.units && series.dataKey.units.length ? series.dataKey.units : this.ctx.trackUnits;
  353 + var yaxis;
  354 + if (keySettings.showSeparateAxis) {
  355 + yaxis = this.createYAxis(keySettings, units);
  356 + this.yaxes.push(yaxis);
  357 + } else {
  358 + yaxis = yaxesMap[units];
  359 + if (!yaxis) {
  360 + yaxis = this.createYAxis(keySettings, units);
  361 + yaxesMap[units] = yaxis;
  362 + this.yaxes.push(yaxis);
  363 + }
  364 + }
  365 + series.yaxisIndex = this.yaxes.indexOf(yaxis);
  366 + series.yaxis = series.yaxisIndex+1;
  367 + yaxis.keysInfo[i] = {hidden: false};
  368 + yaxis.hidden = false;
  369 + }
345 } 370 }
  371 +
346 this.options.colors = colors; 372 this.options.colors = colors;
  373 + this.options.yaxes = angular.copy(this.yaxes);
347 if (this.chartType === 'line' || this.chartType === 'bar') { 374 if (this.chartType === 'line' || this.chartType === 'bar') {
348 if (this.chartType === 'bar') { 375 if (this.chartType === 'bar') {
349 this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; 376 this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
@@ -373,6 +400,23 @@ export default class TbFlot { @@ -373,6 +400,23 @@ export default class TbFlot {
373 } 400 }
374 } 401 }
375 402
  403 + createYAxis(keySettings, units) {
  404 + var yaxis = angular.copy(this.yaxis);
  405 +
  406 + var label = keySettings.axisTitle && keySettings.axisTitle.length ? keySettings.axisTitle : yaxis.label;
  407 + var tickDecimals = angular.isDefined(keySettings.axisTickDecimals) ? keySettings.axisTickDecimals : 0;
  408 + var position = keySettings.axisPosition && keySettings.axisPosition.length ? keySettings.axisPosition : "left";
  409 +
  410 + yaxis.label = label;
  411 + yaxis.tickUnits = units;
  412 + yaxis.tickDecimals = tickDecimals;
  413 + yaxis.alignTicksWithAxis = position == "right" ? 1 : null;
  414 + yaxis.position = position;
  415 +
  416 + yaxis.keysInfo = [];
  417 + return yaxis;
  418 + }
  419 +
376 update() { 420 update() {
377 if (this.updateTimeoutHandle) { 421 if (this.updateTimeoutHandle) {
378 this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle); 422 this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle);
@@ -381,17 +425,64 @@ export default class TbFlot { @@ -381,17 +425,64 @@ export default class TbFlot {
381 if (this.subscription) { 425 if (this.subscription) {
382 if (!this.isMouseInteraction && this.ctx.plot) { 426 if (!this.isMouseInteraction && this.ctx.plot) {
383 if (this.chartType === 'line' || this.chartType === 'bar') { 427 if (this.chartType === 'line' || this.chartType === 'bar') {
  428 +
  429 + var axisVisibilityChanged = false;
  430 + if (this.yaxis) {
  431 + for (var i = 0; i < this.subscription.data.length; i++) {
  432 + var series = this.subscription.data[i];
  433 + var yaxisIndex = series.yaxisIndex;
  434 + if (this.yaxes[yaxisIndex].keysInfo[i].hidden != series.dataKey.hidden) {
  435 + this.yaxes[yaxisIndex].keysInfo[i].hidden = series.dataKey.hidden;
  436 + axisVisibilityChanged = true;
  437 + }
  438 + }
  439 + if (axisVisibilityChanged) {
  440 + this.options.yaxes.length = 0;
  441 + for (var y = 0; y < this.yaxes.length; y++) {
  442 + var yaxis = this.yaxes[y];
  443 + var hidden = true;
  444 + for (var k = 0; k < yaxis.keysInfo.length; k++) {
  445 + if (yaxis.keysInfo[k]) {
  446 + hidden = hidden && yaxis.keysInfo[k].hidden;
  447 + }
  448 + }
  449 + yaxis.hidden = hidden
  450 + var newIndex = -1;
  451 + if (!yaxis.hidden) {
  452 + this.options.yaxes.push(yaxis);
  453 + newIndex = this.options.yaxes.length;
  454 + }
  455 + for (k = 0; k < yaxis.keysInfo.length; k++) {
  456 + if (yaxis.keysInfo[k]) {
  457 + this.subscription.data[k].yaxis = newIndex;
  458 + }
  459 + }
  460 +
  461 + }
  462 + this.options.yaxis = {
  463 + show: this.options.yaxes.length ? true : false
  464 + };
  465 + }
  466 + }
  467 +
384 this.options.xaxis.min = this.subscription.timeWindow.minTime; 468 this.options.xaxis.min = this.subscription.timeWindow.minTime;
385 this.options.xaxis.max = this.subscription.timeWindow.maxTime; 469 this.options.xaxis.max = this.subscription.timeWindow.maxTime;
386 - this.ctx.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime;  
387 - this.ctx.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime;  
388 if (this.chartType === 'bar') { 470 if (this.chartType === 'bar') {
389 this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; 471 this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
390 - this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;  
391 } 472 }
392 - this.ctx.plot.setData(this.subscription.data);  
393 - this.ctx.plot.setupGrid();  
394 - this.ctx.plot.draw(); 473 +
  474 + if (axisVisibilityChanged) {
  475 + this.redrawPlot();
  476 + } else {
  477 + this.ctx.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime;
  478 + this.ctx.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime;
  479 + if (this.chartType === 'bar') {
  480 + this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
  481 + }
  482 + this.ctx.plot.setData(this.subscription.data);
  483 + this.ctx.plot.setupGrid();
  484 + this.ctx.plot.draw();
  485 + }
395 } else if (this.chartType === 'pie') { 486 } else if (this.chartType === 'pie') {
396 if (this.ctx.animatedPie) { 487 if (this.ctx.animatedPie) {
397 this.nextPieDataAnimation(true); 488 this.nextPieDataAnimation(true);
@@ -720,6 +811,26 @@ export default class TbFlot { @@ -720,6 +811,26 @@ export default class TbFlot {
720 "title": "Show points", 811 "title": "Show points",
721 "type": "boolean", 812 "type": "boolean",
722 "default": false 813 "default": false
  814 + },
  815 + "showSeparateAxis": {
  816 + "title": "Show separate axis",
  817 + "type": "boolean",
  818 + "default": false
  819 + },
  820 + "axisTitle": {
  821 + "title": "Axis title",
  822 + "type": "string",
  823 + "default": ""
  824 + },
  825 + "axisTickDecimals": {
  826 + "title": "Axis tick number of digits after floating point",
  827 + "type": "number",
  828 + "default": 0
  829 + },
  830 + "axisPosition": {
  831 + "title": "Axis position",
  832 + "type": "string",
  833 + "default": "left"
723 } 834 }
724 }, 835 },
725 "required": ["showLines", "fillLines", "showPoints"] 836 "required": ["showLines", "fillLines", "showPoints"]
@@ -727,7 +838,26 @@ export default class TbFlot { @@ -727,7 +838,26 @@ export default class TbFlot {
727 "form": [ 838 "form": [
728 "showLines", 839 "showLines",
729 "fillLines", 840 "fillLines",
730 - "showPoints" 841 + "showPoints",
  842 + "showSeparateAxis",
  843 + "axisTitle",
  844 + "axisTickDecimals",
  845 + {
  846 + "key": "axisPosition",
  847 + "type": "rc-select",
  848 + "multiple": false,
  849 + "items": [
  850 + {
  851 + "value": "left",
  852 + "label": "Left"
  853 + },
  854 + {
  855 + "value": "right",
  856 + "label": "Right"
  857 + }
  858 + ]
  859 + }
  860 +
731 ] 861 ]
732 } 862 }
733 } 863 }
@@ -754,6 +884,17 @@ export default class TbFlot { @@ -754,6 +884,17 @@ export default class TbFlot {
754 } 884 }
755 } 885 }
756 886
  887 + redrawPlot() {
  888 + if (this.ctx.plot) {
  889 + this.ctx.plot.destroy();
  890 + if (this.chartType === 'pie' && this.ctx.animatedPie) {
  891 + this.ctx.plot = $.plot(this.$element, this.pieData, this.options);
  892 + } else {
  893 + this.ctx.plot = $.plot(this.$element, this.subscription.data, this.options);
  894 + }
  895 + }
  896 + }
  897 +
757 destroy() { 898 destroy() {
758 if (this.ctx.plot) { 899 if (this.ctx.plot) {
759 this.ctx.plot.destroy(); 900 this.ctx.plot.destroy();
@@ -968,6 +1109,8 @@ export default class TbFlot { @@ -968,6 +1109,8 @@ export default class TbFlot {
968 hoverIndex: hoverIndex, 1109 hoverIndex: hoverIndex,
969 color: series.dataKey.color, 1110 color: series.dataKey.color,
970 label: series.dataKey.label, 1111 label: series.dataKey.label,
  1112 + units: series.dataKey.units,
  1113 + decimals: series.dataKey.decimals,
971 time: pointTime, 1114 time: pointTime,
972 distance: hoverDistance, 1115 distance: hoverDistance,
973 index: i 1116 index: i