Commit b855d82f7a2abc54d6701f69f8c097bfd24029de
Merge branch 'master' of github.com:thingsboard/thingsboard
Showing
8 changed files
with
81 additions
and
30 deletions
... | ... | @@ -169,15 +169,7 @@ export default class Subscription { |
169 | 169 | }); |
170 | 170 | this.registrations.push(registration); |
171 | 171 | } else { |
172 | - registration = this.ctx.$scope.$watch(function () { | |
173 | - return subscription.timeWindowConfig; | |
174 | - }, function (newTimewindow, prevTimewindow) { | |
175 | - if (!angular.equals(newTimewindow, prevTimewindow)) { | |
176 | - subscription.unsubscribe(); | |
177 | - subscription.subscribe(); | |
178 | - } | |
179 | - }); | |
180 | - this.registrations.push(registration); | |
172 | + this.startWatchingTimewindow(); | |
181 | 173 | } |
182 | 174 | } |
183 | 175 | |
... | ... | @@ -188,6 +180,29 @@ export default class Subscription { |
188 | 180 | this.registrations.push(registration); |
189 | 181 | } |
190 | 182 | |
183 | + startWatchingTimewindow() { | |
184 | + var subscription = this; | |
185 | + this.timeWindowWatchRegistration = this.ctx.$scope.$watch(function () { | |
186 | + return subscription.timeWindowConfig; | |
187 | + }, function (newTimewindow, prevTimewindow) { | |
188 | + if (!angular.equals(newTimewindow, prevTimewindow)) { | |
189 | + subscription.unsubscribe(); | |
190 | + subscription.subscribe(); | |
191 | + } | |
192 | + }, true); | |
193 | + this.registrations.push(this.timeWindowWatchRegistration); | |
194 | + } | |
195 | + | |
196 | + stopWatchingTimewindow() { | |
197 | + if (this.timeWindowWatchRegistration) { | |
198 | + this.timeWindowWatchRegistration(); | |
199 | + var index = this.registrations.indexOf(this.timeWindowWatchRegistration); | |
200 | + if (index > -1) { | |
201 | + this.registrations.splice(index, 1); | |
202 | + } | |
203 | + } | |
204 | + } | |
205 | + | |
191 | 206 | initRpc() { |
192 | 207 | |
193 | 208 | if (this.targetDeviceAliasIds && this.targetDeviceAliasIds.length > 0) { |
... | ... | @@ -335,9 +350,9 @@ export default class Subscription { |
335 | 350 | var subscription = this; |
336 | 351 | this.cafs['dataUpdated'] = this.ctx.tbRaf(function() { |
337 | 352 | try { |
338 | - subscription.callbacks.onDataUpdated(this, apply); | |
353 | + subscription.callbacks.onDataUpdated(subscription, apply); | |
339 | 354 | } catch (e) { |
340 | - subscription.callbacks.onDataUpdateError(this, e); | |
355 | + subscription.callbacks.onDataUpdateError(subscription, e); | |
341 | 356 | } |
342 | 357 | }); |
343 | 358 | if (apply) { |
... | ... | @@ -354,9 +369,13 @@ export default class Subscription { |
354 | 369 | this.ctx.dashboardTimewindowApi.onResetTimewindow(); |
355 | 370 | } else { |
356 | 371 | if (this.originalTimewindow) { |
372 | + this.stopWatchingTimewindow(); | |
357 | 373 | this.timeWindowConfig = angular.copy(this.originalTimewindow); |
358 | 374 | this.originalTimewindow = null; |
359 | 375 | this.callbacks.timeWindowUpdated(this, this.timeWindowConfig); |
376 | + this.unsubscribe(); | |
377 | + this.subscribe(); | |
378 | + this.startWatchingTimewindow(); | |
360 | 379 | } |
361 | 380 | } |
362 | 381 | } |
... | ... | @@ -365,11 +384,15 @@ export default class Subscription { |
365 | 384 | if (this.useDashboardTimewindow) { |
366 | 385 | this.ctx.dashboardTimewindowApi.onUpdateTimewindow(startTimeMs, endTimeMs); |
367 | 386 | } else { |
387 | + this.stopWatchingTimewindow(); | |
368 | 388 | if (!this.originalTimewindow) { |
369 | 389 | this.originalTimewindow = angular.copy(this.timeWindowConfig); |
370 | 390 | } |
371 | 391 | this.timeWindowConfig = this.ctx.timeService.toHistoryTimewindow(this.timeWindowConfig, startTimeMs, endTimeMs); |
372 | 392 | this.callbacks.timeWindowUpdated(this, this.timeWindowConfig); |
393 | + this.unsubscribe(); | |
394 | + this.subscribe(); | |
395 | + this.startWatchingTimewindow(); | |
373 | 396 | } |
374 | 397 | } |
375 | 398 | ... | ... |
... | ... | @@ -72,7 +72,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
72 | 72 | scope.$watch("deviceId", function(newVal, prevVal) { |
73 | 73 | if (newVal && !angular.equals(newVal, prevVal)) { |
74 | 74 | scope.resetFilter(); |
75 | - scope.getDeviceAttributes(); | |
75 | + scope.getDeviceAttributes(false, true); | |
76 | 76 | } |
77 | 77 | }); |
78 | 78 | |
... | ... | @@ -81,7 +81,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
81 | 81 | scope.mode = 'default'; |
82 | 82 | scope.query.search = null; |
83 | 83 | scope.selectedAttributes = []; |
84 | - scope.getDeviceAttributes(); | |
84 | + scope.getDeviceAttributes(false, true); | |
85 | 85 | } |
86 | 86 | }); |
87 | 87 | |
... | ... | @@ -117,15 +117,25 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
117 | 117 | } |
118 | 118 | } |
119 | 119 | |
120 | - scope.getDeviceAttributes = function(forceUpdate) { | |
120 | + scope.onReorder = function() { | |
121 | + scope.getDeviceAttributes(false, false); | |
122 | + } | |
123 | + | |
124 | + scope.onPaginate = function() { | |
125 | + scope.getDeviceAttributes(false, false); | |
126 | + } | |
127 | + | |
128 | + scope.getDeviceAttributes = function(forceUpdate, reset) { | |
121 | 129 | if (scope.attributesDeferred) { |
122 | 130 | scope.attributesDeferred.resolve(); |
123 | 131 | } |
124 | 132 | if (scope.deviceId && scope.attributeScope) { |
125 | - scope.attributes = { | |
126 | - count: 0, | |
127 | - data: [] | |
128 | - }; | |
133 | + if (reset) { | |
134 | + scope.attributes = { | |
135 | + count: 0, | |
136 | + data: [] | |
137 | + }; | |
138 | + } | |
129 | 139 | scope.checkSubscription(); |
130 | 140 | scope.attributesDeferred = deviceService.getDeviceAttributes(scope.deviceId, scope.attributeScope.value, |
131 | 141 | scope.query, function(attributes, update, apply) { | ... | ... |
... | ... | @@ -126,7 +126,7 @@ |
126 | 126 | </md-toolbar> |
127 | 127 | <md-table-container ng-show="mode!='widget'"> |
128 | 128 | <table md-table md-row-select multiple="" ng-model="selectedAttributes" md-progress="attributesDeferred.promise"> |
129 | - <thead md-head md-order="query.order" md-on-reorder="getDeviceAttributes"> | |
129 | + <thead md-head md-order="query.order" md-on-reorder="onReorder"> | |
130 | 130 | <tr md-row> |
131 | 131 | <th md-column md-order-by="lastUpdateTs"><span>Last update time</span></th> |
132 | 132 | <th md-column md-order-by="key"><span>Key</span></th> |
... | ... | @@ -147,7 +147,7 @@ |
147 | 147 | </md-table-container> |
148 | 148 | <md-table-pagination ng-show="mode!='widget'" md-limit="query.limit" md-limit-options="[5, 10, 15]" |
149 | 149 | md-page="query.page" md-total="{{attributes.count}}" |
150 | - md-on-paginate="getDeviceAttributes" md-page-select> | |
150 | + md-on-paginate="onPaginate" md-page-select> | |
151 | 151 | </md-table-pagination> |
152 | 152 | <ul flex rn-carousel ng-if="mode==='widget'" class="widgets-carousel" |
153 | 153 | rn-carousel-index="widgetsCarousel.index" | ... | ... |
... | ... | @@ -374,6 +374,10 @@ export default class TbFlot { |
374 | 374 | } |
375 | 375 | |
376 | 376 | update() { |
377 | + if (this.updateTimeoutHandle) { | |
378 | + this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle); | |
379 | + this.updateTimeoutHandle = null; | |
380 | + } | |
377 | 381 | if (this.subscription) { |
378 | 382 | if (!this.isMouseInteraction && this.ctx.plot) { |
379 | 383 | if (this.chartType === 'line' || this.chartType === 'bar') { |
... | ... | @@ -396,6 +400,11 @@ export default class TbFlot { |
396 | 400 | this.ctx.plot.draw(); |
397 | 401 | } |
398 | 402 | } |
403 | + } else if (this.isMouseInteraction && this.ctx.plot){ | |
404 | + var tbFlot = this; | |
405 | + this.updateTimeoutHandle = this.ctx.$scope.$timeout(function() { | |
406 | + tbFlot.update(); | |
407 | + }, 30, false); | |
399 | 408 | } |
400 | 409 | } |
401 | 410 | } | ... | ... |
... | ... | @@ -217,7 +217,9 @@ export default class TbGoogleMap { |
217 | 217 | this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34); |
218 | 218 | } |
219 | 219 | |
220 | - this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo); | |
220 | + if (settings.displayTooltip) { | |
221 | + this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo); | |
222 | + } | |
221 | 223 | |
222 | 224 | if (onClickListener) { |
223 | 225 | marker.addListener('click', onClickListener); | ... | ... |
... | ... | @@ -19,7 +19,7 @@ import tinycolor from 'tinycolor2'; |
19 | 19 | import TbGoogleMap from './google-map'; |
20 | 20 | import TbOpenStreetMap from './openstreet-map'; |
21 | 21 | |
22 | -function procesTooltipPattern(tbMap, pattern, datasources) { | |
22 | +function procesTooltipPattern(tbMap, pattern, datasources, dsIndex) { | |
23 | 23 | var match = tbMap.varsRegex.exec(pattern); |
24 | 24 | var replaceInfo = {}; |
25 | 25 | replaceInfo.variables = []; |
... | ... | @@ -48,11 +48,13 @@ function procesTooltipPattern(tbMap, pattern, datasources) { |
48 | 48 | var offset = 0; |
49 | 49 | for (var i=0;i<datasources.length;i++) { |
50 | 50 | var datasource = datasources[i]; |
51 | - for (var k = 0; k < datasource.dataKeys.length; k++) { | |
52 | - var dataKey = datasource.dataKeys[k]; | |
53 | - if (dataKey.label === label) { | |
54 | - variableInfo.dataKeyIndex = offset + k; | |
55 | - break; | |
51 | + if (angular.isUndefined(dsIndex) || dsIndex == i) { | |
52 | + for (var k = 0; k < datasource.dataKeys.length; k++) { | |
53 | + var dataKey = datasource.dataKeys[k]; | |
54 | + if (dataKey.label === label) { | |
55 | + variableInfo.dataKeyIndex = offset + k; | |
56 | + break; | |
57 | + } | |
56 | 58 | } |
57 | 59 | } |
58 | 60 | offset += datasource.dataKeys.length; |
... | ... | @@ -168,6 +170,7 @@ export default class TbMapWidget { |
168 | 170 | latKeyName: localLatKeyName, |
169 | 171 | lngKeyName: localLngKeyName, |
170 | 172 | showLabel: subscriptionLocationSettings.showLabel !== false, |
173 | + displayTooltip: subscriptionLocationSettings.displayTooltip !== false, | |
171 | 174 | label: datasource.name, |
172 | 175 | labelColor: this.ctx.widgetConfig.color || '#000000', |
173 | 176 | color: "#FE7569", |
... | ... | @@ -179,10 +182,10 @@ export default class TbMapWidget { |
179 | 182 | useMarkerImageFunction: false, |
180 | 183 | markerImageFunction: null, |
181 | 184 | markerImages: [], |
182 | - tooltipPattern: "<b>Latitude:</b> ${#"+latKeyIndex+":7}<br/><b>Longitude:</b> ${#"+lngKeyIndex+":7}" | |
185 | + tooltipPattern: subscriptionLocationSettings.tooltipPattern || "<b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}" | |
183 | 186 | }; |
184 | 187 | |
185 | - locationsSettings.tooltipReplaceInfo = procesTooltipPattern(this, locationsSettings.tooltipPattern, this.subscription.datasources); | |
188 | + locationsSettings.tooltipReplaceInfo = procesTooltipPattern(this, locationsSettings.tooltipPattern, this.subscription.datasources, i); | |
186 | 189 | |
187 | 190 | locationsSettings.useColorFunction = subscriptionLocationSettings.useColorFunction === true; |
188 | 191 | if (angular.isDefined(subscriptionLocationSettings.colorFunction) && subscriptionLocationSettings.colorFunction.length > 0) { |
... | ... | @@ -211,6 +214,7 @@ export default class TbMapWidget { |
211 | 214 | latKeyName: "lat", |
212 | 215 | lngKeyName: "lng", |
213 | 216 | showLabel: true, |
217 | + displayTooltip: true, | |
214 | 218 | label: "", |
215 | 219 | labelColor: this.ctx.widgetConfig.color || '#000000', |
216 | 220 | color: "#FE7569", | ... | ... |
... | ... | @@ -109,7 +109,9 @@ export default class TbOpenStreetMap { |
109 | 109 | this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34); |
110 | 110 | } |
111 | 111 | |
112 | - this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo); | |
112 | + if (settings.displayTooltip) { | |
113 | + this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo); | |
114 | + } | |
113 | 115 | |
114 | 116 | if (onClickListener) { |
115 | 117 | marker.on('click', onClickListener); | ... | ... |